Azure Functions 2.0 / Dependency Injection /Azure Key Vault Configuration

There is no question that keeping your config settings safe is paramount. Its also no secret that the use of dependency injection makes for cleaner, more testable code. Azure’s server less functions are a great choice for creating scalable APIs. In this article I want to show how we can use dependency injection within Azure Functions 2.0 and also lock down the configuration settings. We achieve this by connecting our Azure function to Azure Key Vault (AKV) and allowing for the function to read secrets from the AKV. Let’s see how this works.

Azure Functions 2.0 Dependency Injection

What is great about Azure Functions 2.0 is that achieving DI is very simple and clean.

[assembly: FunctionsStartup(typeof(FunctionDISample.Startup))]
namespace FunctionDISample
{
    public class Startup : FunctionsStartup
    {
    }

    public override void Configure(IFunctionsHostBuilder builder)
    {
       AddDependencyInjection(builder);
    }

    private void AddDependencyInjection(IFunctionsHostBuilder builder)
    {
        builder.Services.AddSingleton();
        builder.Services.AddSingleton();
        builder.Services.AddSingleton();
        builder.Services.AddSingleton();
     }
    }
}

In our startup code of that Azure function, we need to register the services that will be used. Add a Startup.cs class to your function project. Within the startup class add the following code

The key is telling the function that this is the startup class via the line

[assembly: FunctionsStartup(typeof(FunctionDISample.Startup))]

The other key is the override of the Configure method. This is the location to register all of our dependencies. There is a great Microsoft article located here on how to do dependency injections. The one thing I am suggesting to do differently is not do the custom settings that are detailed in this article but rather achieve that through “secrets” in AKV.

Next, its really simple to get access to are injected services within our functions. Here is a sample implementation of what a function what look like.

 public  class TelemetryFileProcessor
    {
        private IGenericManager _manager;
        public TelemetryFileProcessor(IGenericManager manager)
        {
            _manager = manager;
        }

        [FunctionName("ProcessFile")]
        public   void ProcessFile([BlobTrigger("%BlobContainer%", Connection = "BlobStorageConnectionString")]Stream myBlob, string name, ILogger log)
        {
            log.LogInformation($"Starting ProcessFile \n Name:{name} \n Size: {myBlob.Length} Bytes");
            _manager.ProcessTelemetryFile(myBlob, name);
            log.LogInformation($"Completed ProcessFile \n Name:{name} \n Size: {myBlob.Length} Bytes");
        }
    }

You may notice that the function is no longer static. This is a difference between v1 and v2 of funtions, they no longer are required to be static methods. This allows for use to inject our services into the function via the constructor.

Connecting Application Settings to Azure Key Vault

The Key Vault references feature of AKV makes it possible to make your app settings get initialized from secrets hosted in AKV. The full details is located here but for brevity I am going to focus on the main points.

First, within your Application Settings for the function app, we can add key value pairs that proxy into AKV secrets. For example

Key Name : DBConnection

Key Value: @Microsoft.KeyVault(SecretUri= https://myvault.vault.azure.net/secrets/dbconnection/ec96f02080254f109c51a1f14cdb1931

What this is saying is that application configuration will look for a secret called “dbconnection” inside the AKV myvault.vault.azure.net. Your application settings should look something like this

In order for the Azure Function to communicate with AKF, the system assigned managed indentity for the function application needs to be given get rights. In order to determine the system managed identity navigate to the Azure Functions Platform Settings

Select the Identity menu option. Once on the Identity screen, copy the Object Id.

We then need to tell AKV that this “Object Id” which is the MSI the function is allowed to read from AKV. To do that, open powershell, login into azure and then run the following command.

Once this command is run, navigate back to the function and view the configurations for the Azure function. It should look something like this

az keyvault set-policy -n 'nameofazurekeyvault' -g 'nameofresourcegrooup' --object-id '94ccc45a-66aa-466b-8345-08f3038cxxxx' --secret-permissions get

In this case we can see that we have 2 configuration settings that reference AKV. When the application runs now, those two configuration settings will be loaded with the value from the secret from within AKV.

That’s all there is to it. Clean approach to supporting both dependency injection and configuration values obtained from Azure Key Vault with Azure Functions 2.0

Leave a Reply