Using Azure App Configuration in .NET 5 Functions
Tags: azure, dotnet, serverless
Published: 2021-03-30 15:38:57

## Azure .NET 5 Functions

A lot has been said about .NET 5 support for Azure Functions. The most important news: it is now officially supported! 🥳 To enable running
Azure Functions with .NET 5, the new **Isolated Model** enables Functions to run as an out-of-process language worker separate from the
Azure Functions runtime. This way you'll have full control over the Function's dependencies on one hand, and new features like a middleware
pipeline on the other. For an awesome write-up about everything around this, check out Oscar van Tol's post
[Azure Functions in .NET 5 and beyond](https://dev.to/oscarvantol/azure-functions-in-net-5-and-beyond-26d6).

## Azure App Configuration

>Azure App Configuration provides a service to centrally manage application settings and feature flags. Modern programs, especially programs
running in a cloud, generally have many components that are distributed in nature. Spreading configuration settings across these components
can lead to hard-to-troubleshoot errors during an application deployment. Use App Configuration to store all the settings for your
application and secure their accesses in one place.  
[What is Azure App Configuration?](https://docs.microsoft.com/en-us/azure/azure-app-configuration/overview)

For an introduction to Azure App Configuration you can check my previous post
[Azure App Configuration: an introduction](https://www.rickvandenbosch.net/blog/azure-app-configuration-an-introduction).

## Bringing the two together

To enable using App Configuration in .NET 5 Functions, you can use the `AddAzureAppConfiguration` extension method to add App Configuration
as a source to the `IConfigurationBuilder`. This extension method can be found in NuGet package
[Microsoft.Extensions.Configuration.AzureAppConfiguration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.AzureAppConfiguration/).
By doing this, you can simply call `GetValue` on `IConfiguration` to get a value. Based on the order you add configuration sources to the
builder, you will be able to fallback through different source.

For example: if you first add Environment Variables (which includes settings.json files, too!) and add App Configuration second, asking for
a setting 'Setting1' will first try to get that value from App Configuration. If it can't be found there, the application will search for
the setting 'Setting1' in Environment variables.

### Wiring up your Functions App

`Program.cs`:

```csharp
public static void Main()
{
    var host = new HostBuilder()
        .ConfigureAppConfiguration(c =>
        {
            // Add Environment Variables since we need to get the App Configuration connection string from settings.
            c.AddEnvironmentVariables();
            // Call Build() so we can get values from the IConfiguration.
            var config = c.Build();
            var connectionString = config.GetValue<string>("AppConfigurationConnectionString");
            // Add Azure App Configuration with the connectionstring.
            c.AddAzureAppConfiguration(connectionString);
        })
        .ConfigureFunctionsWorkerDefaults()
    v.Build();

    host.Run();
}
```

### Getting a value from App Configuration in a Function

`Triggered.cs` (an HttpTriggered Function):

```csharp
public class Triggered
{
    // Private field to hold IConfiguration
    private IConfiguration _configuration;

    // Constructor that gets IConfiguration injected
    public Triggered(IConfiguration configuration)
    {
        _configuration = configuration;    
    }

    [Function("Triggered")]
    public HttpResponseData Run([HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequestData req,
        FunctionContext executionContext)
    {
        var response = req.CreateResponse(HttpStatusCode.OK);
        response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
        // Call GetVallue<string> on IConfiguration to get the setting, this calls out to App Configuration
        var settingOne = _configuration.GetValue<string>("Setting1");
        response.WriteString($"The value of the setting is {settingOne}!");

        return response;
    }
}
```

I tried this with a complete connection string, so including the access key. Of course this can also work without an access key using a
[Managed Identity](https://www.theurlist.com/managedidentity). This eliminates the need for having access keys in code or configuration.

Hope this helps. Happy coding!