Ole Albers
Ole Albers

Reputation: 9305

Configure Azure KeyVault Endpoint in Azure Function V4

I am currently migrating a dotnet-isolated v3 function (.net 5) to a non-isolated v4 azure function (.net 6)

in v3 dotnet-isolated I had a console application and so a Program.cs which contained the following code:

public static void Main()
        {
            var host = new HostBuilder()
                .ConfigureAppConfiguration(AddAzureAppConfig)
                .Build();

            host.Run();
        }

     private static void AddAzureAppConfig(IConfigurationBuilder builder)
        {
            var azureAppConfigurationEndpoint = Environment.GetEnvironmentVariable("AzureAppConfiguration");

            builder.AddAzureAppConfiguration(options =>
                  options.Connect(azureAppConfigurationEndpoint).ConfigureKeyVault(kv =>
                  {
                      kv.SetCredential(new DefaultAzureCredential());
                  }).Select(KeyFilter.Any, LabelFilter.Null)
            );
        }

Now in v4 I have a library instead and so no program.cs. Instead I created a Startup.cs derived from FunctionsStartup

 public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            builder.Services.AddHttpClient();
...
}
}

As far as I understood from this StackOverFlow-Question v4 Azure Functions don't have any IConfigurationBuilder and don't need to if you directly want to access any configuration values.

Now my issue is that while AddAzureAppConfiguration inside the Microsoft.Extension.Configuration.AzureAppConfigurationExtensions has a overload I could use (AddAzureAppConfiguration(this IServiceCollection services)) but it is missing the Action<AzureAppConfigurationOptions> action parameter (which the IConfigurationBuilder- variant had) which I need to add the KeyVault options.

What do I have to modify to use the same approach I was using with my AddAzureAppConfig() that worked on the v3 isolated console application approach?

Upvotes: 4

Views: 5600

Answers (2)

David Yates
David Yates

Reputation: 2220

A better title: How do I configure key vault for Azure App Configuration within a .NET Isolated Azure Function?

For those that are looking for a .NET 6 program.cs example, here is what your program.cs code should look like:

using Azure.Identity;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;


var host = new HostBuilder()
    .ConfigureAppConfiguration(builder =>
    {
        // You might need this depending on your local dev environment
        // var credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions { ExcludeSharedTokenCacheCredential = true });
        var credential = new DefaultAzureCredential();

        // Required NuGet packages for Azure App Configuration:
        // 1. Azure.Identity
        // 2. Microsoft.Extensions.Configuration.AzureAppConfiguration

        var azureAppConfigurationEndpoint = Environment.GetEnvironmentVariable("AzureAppConfigurationEndpoint");

        if (string.IsNullOrWhiteSpace(azureAppConfigurationEndpoint) == false)
        {
            builder.AddAzureAppConfiguration(options =>
            {
                options.Connect(new Uri(azureAppConfigurationEndpoint), credential)
                    .ConfigureKeyVault(kv =>
                    {
                        kv.SetCredential(credential);
                    });
            });
        }
    })
    .ConfigureFunctionsWorkerDefaults(builder =>
    {

    })
    .ConfigureServices((builder, sc) =>
    {
    
    })
    .Build();

host.Run();

Assumptions

  • Your Azure App Configuration endpoint URL is in local.settings.json in a key called "AzureAppConfigurationEndpoint"

Warnings

  • If your intent is to override a connection string for bindings like ServiceBusTrigger or EventHubTrigger for local development/debugging, it will NOT work with ISOLATED Azure Functions! You have two options with ISOLATED Azure Functions:
    1. Put the connection string in the local.settings.json file when developing locally. In the cloud, use the key vault reference syntax to get in key vault entries in your bindings.
    2. Create a connection string that doesn't have any sensitive permission data in it. Give developers permissions in the dev environment (either directly or via a group) to access the resource . In the cloud, use managed identities and grant the Azure Function permission to use the resource.

References

Upvotes: 5

Anthony C
Anthony C

Reputation: 2157

You can override the ConfigureAppConfiguration method in the FunctionsStartup. Inside the method, you can call ConfigurationBuilder.AddAzureKeyVault which is very similar to function v3.

Example below:

    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {


        }

        public override void ConfigureAppConfiguration(IFunctionsConfigurationBuilder builder)
        {
            var builtConfig = builder.ConfigurationBuilder.Build();
            var keyVaultEndpoint = builtConfig["AzureKeyVaultEndpoint"];

            if (!string.IsNullOrEmpty(keyVaultEndpoint))
            {

                var config = builder.ConfigurationBuilder
                        .AddAzureKeyVault(keyVaultEndpoint)
                    .Build();

                var kvSecret = config["kvSecretName"];

            }
        }
    }

The AzureKeyVaultEndpoint is passed in the local.settings.json for local env and in the AppConfig for the Azure env.

Upvotes: 3

Related Questions