Azure Function Structure - azure

I'm trying to wrap my head around how we're supposed to build Azure functions.
I love the idea of building serverless, compact, single-function apps that respond to events.
Here are the problems I'm running into:
I have nice class libraries built in .NET Standard 2 that handle all my "backend needs" namely handling CRUD ops with Cosmos Db, Azure Table Storage, Azure SQL, Redis, Azure Storage. No matter what I did, I couldn't integrate these class libraries into an Azure Functions project. More details below.
Also, getting dependency injection in Azure Functions project has proven to be quite a task -- especially with my class libraries mentioned above.
At this point, the only option I'm seeing is to "copy and paste" code into a new Azure Functions project and use it without any DI.
This seems to go against "best practices". So what's the solution other than either to create monolithic code or wait till Azure Functions support .NET Core and DI.
I thought I could use my .NET Standard class libraries from a regular Azure Functions project targeting .NET Framework. After all, the idea of .NET Standard is to "standardize" things. I opened a couple of posts here on SO. I'm providing the links so that you can see the issues I've run into:
Using .NET Core 2.0 Libraries in WebJob Targeting .NET Framework 4.7
No parameterless constructor error in WebJobs with .NET Core and Ninject
P.S. My previous posts are referring to WebJobs. That was plan B approach because WebJobs seem half a step ahead of Azure Functions when it comes to supporting things like .NET Core and DI. Ultimately, I'd like to build a few Azure Functions that can use my class libraries built in .NET Standard 2.
Also, my previous posts mention that my class libraries target .NET Core 2.0. Since then I converted them to .NET Standard 2 which didn't really take much at all. I did this so that I truly conform to .NET Standard 2.

One issue is that Visual Studio has an outdated version of the Functions Core tools. Until this is resolved, you can work around in the following way:
Install the latest via npm by running npm install -g azure-functions-core-tools
In your Function App in VS, go to the Properties
Go to Debug, and click New... under Profile
Name the new Profile something like FunctionsNpm
Set the executable to (replace [YourUserName]): C:\Users\[YourUserName]\AppData\Roaming\npm\node_modules\azure-functions-core-tools\bin\func.exe
Set the arguments to host start
Set the working directory to $(TargetDir)
In toolbar, look for the green triangle icon to change your current Profile to the one you just created:
Now when you run from VS, you'll be using the npm tools instead of the older one that come with the VS package.

.NET Standard 2 support is on its way, see this github issue.

Related

Using Azure SDK for JS to create .NET 4.x App Service

I'm starting to wonder whether this is the right tool for the job, still here goes.
I'm attempting to automate the creation of our Azure Test environment using Azure SDK for JS. The environment spans many services (as you can imagine), including Classic ASP.NET app services.
Node is my safe space, so that is why I started with the JS SDK.
I have started scripting the creation of an app service using WebSiteManagementClient.webApps.createOrUpdate. I'm confused though, there is seemingly no way to configure any of the following:
Which app service plan the app service should be connected to. This feels fundamental.
The operating system, Windows or Linux.
The stack version, .NET 4.8, .NET Core, or whatever.
Is it possible to configure the above using the JS SDK, or am I going to have find another approach?
Update 23/03/21
Untested, but these are my findings so far:
App Service Plan - The plan is set using the serverFarmId property of the Site interface.
Operating system - Assuming Windows as the default, if you want a Linux app service, you change the kind property of Site from app, to app,linux.
Stack & version - In the SiteConfig interface, you have linuxFxVersion and windowsFxVersion. Again, I think the assumption is 'latest .NET' (e.g. .NET 4.8). For .NET Core 3.1, the setting looks to be DOTNETCORE|3.1.
It can be achieved using js SDK. I checked the source code and it is ok. But I don't recommend to use js sdk to do this.
Because you need to call the SDK, there are many internal logics that you need to code. This will waste a lot of your time. So I recommend you to use restapi.
The restapi method name is similar to the naming in the SDK, mainly because you can test api interfaces online to achieve the functions you want. So you can selectively choose the method you want to achieve the function you want.
Official doc
Web Apps - Create Or Update
As for your concerns, you only need to write all the configuration in json format and put it in the request body.
Tips:
First use the online interface, encode the json format, create a webapp according to your needs, and then integrate it into your code.

Is it possible to publish a .net core web api to azure functions?

I've recently switched jobs from a AWS shop to an Azure shop, both using dotnet. AWS publishes Amazon.Lambda.AspNetCoreServer, which is a magic Nuget package that allows you to write a plain ol' ASP.NET core Web API and deploy it as into a lambda with only a few lines on config. I really loved this pattern because it allows developers to just write a normal web api without having the host runtime leak into their coding.
Does anything like this exist in Azure? Even something that is community supported? Or is there some any way to achieve something like this in Azure Functions?
Unfortunately there is no simple way to do that since Azure function format is a bit different.
[FunctionName(nameof(GetAll))]
public IActionResult GetAll([HttpTrigger("get", Route = "entity")]HttpRequest request)
Then it will generate json with meta data for AF.
If you wish to host pure .net core without any changes I would look into Containers option
PS0: Theoretically it would be possible to do it with little bit of reflection. For instance you create project with all your Asp.Net core apis, which you can use in asp.net core hosting. Then you write tool which grabs your dll and using reflection you find all actions in your controllers and generate code for AF
PS1: Have a look https://github.com/tntwist/NL.Serverless.AspNetCore

Is it recommended to upgrade a deployed v2 azure function to v3 or is it better to create new resources and deploy to them from scratch?

We have a function deployed to azure running the v2 runtime. If I go to the function in the portal to try to upgrade it to v3, I see this message "Cannot upgrade with existing functions: Major version upgrades can introduce breaking changes to languages and bindings. When upgrading major versions of the runtime, consider creating a new function app and migrate your functions to this new app."
However, I was able to change the function in Visual Studio and deploy, using a simple test deploy of right-click publish, and the publishing process upgraded the deployed function to runtime v3.
Are there any gotchas we may run into using this approach? Is it better practice to create new azure function resources to deploy to a clean v3 azure function?
Thanks
Apparently no one else has this question or the answer is obvious. In any case, here's Microsoft's recommendation from their support personnel (grammar/language translation is Microsoft's):
Based on the official documentation changing the version can be made by changing the App Setting "FUNCTIONS_EXTENSION_VERSION" value form ~2 to ~3 however this can cause some problems if there are any dependencies unique to version 2 of the runtime, you can read more about this in the following link
https://learn.microsoft.com/en-us/azure/azure-functions/functions-versions#migrating-from-2x-to-3x
Now based on my experience the safest an easiest way to archive [achieve] this is to deploy the code into a Function app that was created targeting the version 3 of the runtime this is to assure [ensure] that it will only have the dependencies form [from] version 3 and not having anything extra from 2 left after changing the version directly from the portal
The idea with this is to avoid having conflicts from between assets form version 2 or missing assets from version 3
Suppose you are using c# function, if yes, the major update about v2 to v3 is the .net core version. So mostly if your code could work with the update that means your dependencies are compatible with .net core3, so mostly it won't crash.
And there is an official doc about migrating from 2.x to 3.x.
And about deploying, if the runtime is different when you deploy it will prompt to update the portal runtime, so it won't affect the function running.

Logging in Azure and Console app from NuGet library

looking for some advice here on developing a common logging environment for a NuGet package.
I've currently got a private NuGet package created from a C# library that works perfectly for local console apps and as such was written to log to the Windows event log.
Now I want to be able to use that package in an Azure function but of course Azure uses a different logging mechanism.
Any advice on how to create a logging overlay that allows the library to be compiled on my local PC in Visual Studio but also support logging in Azure if the package is used there?
Cheers,
Dave
I believe you are looking for the Microsoft.Extensions.Logging namespace and interface. This interface is used extensively across azure services, .Net 4+ and .Net Core. If you look for related nuget packages you will find multiple implementations for different logging scenarios and tools, including native sinks like event logs, functions, console as well as custom sinks like Splunk and Serilog.
If you separate your logging implementation from your application/package code and implement Microsoft.Extensions.Logging and adhere to the interface, then your logging interface can be easily plumbed in to many supported sinks, including functions.
A previous answer of mine provides an earlier, more manual approach to this problem. See here.

Azure Function gives error: System.Drawing is not supported on this platform

(If this question is poorly worded, could someone please help me clear it up?)
I have an Azure Function (2.0) which relies on some System.Drawing code. I've added a NuGet reference to System.Drawing.Common (4.5.0).
After publishing the app, however, when the function is called, it produces the error:
System.Private.CoreLib: Exception while executing function:
[MyFunctionName]. System.Drawing.Common: System.Drawing is not
supported on this platform.
As far as I'm aware, System.Drawing.Common is supported on .NET Core now, which I believe is the environment in which my Azure Function is running. The actual project is a .NET Standard 2.0 project, though.
I am confused as to how to resolve this. I've tried converting the project to a .NET Core 2.1 project but that led to bizarre errors related to "Metadata generation failed" and an inability to find System.Runtime.
My project references Microsoft.Azure.WebJobs.Extensions.EventGrid (2.0.0-beta2) if that's relevant.
It's not about the CLR, it's about the sandbox.
System.Drawing relies heavily on GDI/GDI+ to do its thing. Because of the somewhat risky nature of those APIs (large attack surface) they are restricted in the App Service sandbox.
Win32k.sys (User32/GDI32) Restrictions
For the sake of radical attack surface area reduction, the sandbox prevents almost all of the Win32k.sys APIs from being called, which practically means that most of User32/GDI32 system calls are blocked. For most applications this is not an issue since most Azure Web Apps do not require access to Windows UI functionality (they are web applications after all).
Try to find an different library that doesn't rely on System.Drawing/GDI, like ImageSharp.
A little update can help a lot of people.
Now you can switch your Azure Function to v3:
in Function app settings panel -> Runtime version ~3
With this setup, your code run in a sandbox that support Core 3, (you don't need to rebuild your dll to Core3, i run my .net core 2.1 dll without errors), and surprise... you don't get this exception anymore:
System.Drawing.Common: System.Drawing is not supported on this platform.
Because the CLI can found GDI/GDI+ that need in the subsystem.
Now i can convert html to pdf without go crazy.

Resources