Convert from Configuration.AzureKeyVault to Configuration.Secrets

After building my example for implementing Azure Key Vault configuration provider I found out that particular package is being deprecated.

After building my example for implementing Azure Key Vault configuration provider I found out that particular package is being deprecated. Finding documentation on how to convert from the old way to the new was lacking.

Now that the NuGet package Microsoft.Extensions.Configuration.AzureKeyVault is changing to Azure.Extensions.AspNetCore.Configuration.Secrets I needed to change my example of implementing the new package. There wasn't much documentation on how to do it, so here it some.

First off, here's the companion code, https://github.com/veccsolutions/Vecc.Examples.Vault/tree/ConvertToAzureExtensions

A general overview of the needed changes were to update the NuGet packages, add a using statement, use the correct credential class and use the updated extension method.

NuGet changes

  • Remove Microsoft.Extensions.Configuration.AzureKeyVault
  • Add Azure.Extensions.AspNetCore.Configuration.Secrets
  • Add Azure.Identity

The extensions package adds the configuration provider and by reference, Azure Key Vault client and supporting classes along with some other core Azure packages.

The identity package adds the necessary TokenCredential classes to be able to use the SecretClient.

One thing I found is that the credential classes now require the tenant id. The old client didn't need that, so you'll need to bring that in.

Using statement changes

Since I built up my client in my program class I added the Azure.Identity using statement to the top.

using Azure.Identity;

Credential class

To use the new AddAzureKeyVault extension method, you will need to create a TokenCredential. Since I'm using a client id and secret, I used ClientSecretCredential. That line of code is the following

var credential = new ClientSecretCredential(tenantId, clientId, clientSecret);

Update extension method

I then passed that in to the AddAzureKeyVault along with my custom secret manager. If you don't want that (most people probably won't). Just exclude that parameter. The new line looks like this.

configurationBuilder.AddAzureKeyVault(new Uri(vault), credential, new DottableKeyVaultSecretManager());

New program.cs

My entire program.cs file would look like this

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

namespace Vecc.Examples.Vault
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration(configurationBuilder =>
                {
                    var builtConfig = configurationBuilder.Build();
                    var keyVaultConfig = builtConfig.GetSection("KeyVault");
                    var vault = keyVaultConfig["vault"];
                    var clientId = keyVaultConfig["clientId"];
                    var clientSecret = keyVaultConfig["secret"];
                    var tenantId = keyVaultConfig["tenantId"];

                    var credential = new ClientSecretCredential(tenantId, clientId, clientSecret);
                    configurationBuilder.AddAzureKeyVault(new Uri(vault), credential, new DottableKeyVaultSecretManager());
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }
}

Custom KeyVaultSecretManager

With adding the configuration provider updated we will now update my example DottableKeyVaultSecretManager. You can see how I use this class to support periods in my configuration with the key vault here https://www.frakkingsweet.com/using-periods-in-azure-keyvault-and-net-core-options/.

The changes are simple, update the using statements by

  • Add Azure.Extensions.AspNetCore.Configuration.Secrets;
  • Add Azure.Security.KeyVault.Secrets;
  • Remove Microsoft.Extensions.Configuration.AzureKeyVault;

The following changes to the class were made

  • DefaultKeyVaultSecretManager changed to KeyVaultSecretManager
  • SecretBundle changed to KeyVaultSecret
  • The property chain SecretIdentifier.Name changed to just Name.

And my final class is this

using Azure.Extensions.AspNetCore.Configuration.Secrets;
using Azure.Security.KeyVault.Secrets;
using Microsoft.Extensions.Configuration;

namespace Vecc.Examples.Vault
{
    public class DottableKeyVaultSecretManager : KeyVaultSecretManager
    {
        public override string GetKey(KeyVaultSecret secret)
        {
            var result = secret.Name.Replace("---", ".").Replace("--", ConfigurationPath.KeyDelimiter);

            return result;
        }
    }
}

Conclusion

It would have been nice to see some kind of documentation on how to change to the new package. It would be even nicer to see a note on the documentation of the old package to switch to this new package. At least it didn't take too long to figure it all out and everything that worked in the old one still worked in the new.