0
votes

I have an appsettings.json file where I want to transform the value located at:

"ConnectionStrings": {
  "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=MyDatabase;Trusted_Connection=True;MultipleActiveResultSets=true"
},

I found the following answer so I know that an app service can retrieve values directly from the key vault:

https://stackoverflow.com/a/59994040/3850405

This is not the reason for asking. Since Microsoft offers JSON variable substitution I still think this should be possible since the only problem is the nested value. The question above is similar but I would like to specify a bit more what has already been tested and where I got stuck.

https://docs.microsoft.com/en-us/azure/devops/pipelines/tasks/transforms-variable-substitution?view=azure-devops&tabs=Classic#json-variable-substitution

It is possible to use Pipelines -> Library -> Variable group

enter image description here

or a Azure Key Vault Task to get the secret value.

enter image description here

The problem is the secret value can not contain dots:

enter image description here

Please provide a valid secret name. Secret names can only contain alphanumeric characters and dashes.

Neither in a linked Variable group or in a Azure Key Vault Task I'm allowed to rewrite a secret name to another variable name.

Looking at the sample below if the secret name was ConnectionStringsDefaultConnection I could access the value like this $(ConnectionStringsDefaultConnection) but I don't know how to rename it.

https://azuredevopslabs.com/labs/vstsextend/azurekeyvault/

I have found a task that could get the job done but it requires a third party Release task. This is not acceptable since the project only allows Tasks written by Microsoft.

enter image description here

https://daniel-krzyczkowski.github.io/How-to-inject-Azure-Key-Vault-secrets-in-the-Azure-DevOps-CICD-pipelines/

I also know that a Pipeline variable can be used to store the value but we wan't to have a single source of truth and that is the Azure Key Vault Secret.

enter image description here

2

2 Answers

2
votes

Read a similar question from VSTS (Visual Studio Team Services) and was able to solve it.

Created a Pipeline variable called ConnectionStrings.DefaultConnection that had a reference value to my linked variable group.

If my secret was named ConnectionStringsDefaultConnection I would hook this up as a linked variable and then add $(ConnectionStringsDefaultConnection) as a value.

enter image description here

Source:

https://stackoverflow.com/a/47787972/3850405

1
votes

One of the option will be to use Key Vault directly in your application instead of replacing your appsettings.json. You can configure this in CreateHostBuilder method:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration((context, config) =>
        {
            if (context.HostingEnvironment.IsProduction())
            {
                var builtConfig = config.Build();

                using (var store = new X509Store(StoreLocation.CurrentUser))
                {
                    store.Open(OpenFlags.ReadOnly);
                    var certs = store.Certificates
                        .Find(X509FindType.FindByThumbprint,
                            builtConfig["AzureADCertThumbprint"], false);

                    config.AddAzureKeyVault(
                        $"https://{builtConfig["KeyVaultName"]}.vault.azure.net/",
                        builtConfig["AzureADApplicationId"],
                        certs.OfType<X509Certificate2>().Single());

                    store.Close();
                }
            }
        })
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

Please check the documentation.