1

I have setup the Key-Vault secret in Azure for connection string and updated my web config file as shown below and it is working fine. Now my question is if I need to provide a separate connection string for QA, dev, staging or other environment, prior to deploy to the to the Azure app service would I manually update the connection string name? Is there any way that I don't have to change the name as per the environment. (I am doing the deployment manually and CI/CD is not involved>

<connectionStrings configBuilders="AzureKeyVault">
  <add name="ProductionConnstr" connectionString="from key vault" 
        providerName="System.Data.SqlClient" />
</connectionStrings>

Edit:

I have used the connected service to generate and to get the nuget package. The code run fine and connection string is being picked from the Key Vault secret but when I am getting error when deploying the code to web app. Below is the auto generated code. I wonder if I am missing something else that is needed. I am using MVC 4.7.2

Error:

A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: TCP Provider, error: 0 - A connection attempt failed.

web config code.

<configSections><section name="configBuilders" 
      type="System.Configuration.ConfigurationBuildersSection, 
      System.Configuration, Version=4.0.0.0, Culture=neutral, 
     PublicKeyToken=b03f5f7f22d50a3a" 
 restartOnExternalChanges="false" 
 requirePermission="false" />
</configSections>
 <configBuilders>
   <builders>
<add name="AzureKeyVault" vaultName="Prod-ConSt-01" type 
      "Microsoft.Configuration.ConfigurationBuilders.AzureKeyVaultConfigBuilder,
     Microsoft.Configuration.ConfigurationBuilders.Azure, Version=2.0.0.0, Culture=neutral,
     PublicKeyToken=31bf9256ad364e35"
     vaultUri="https://mywebsite-prod-const-01.vault.azure.net/" />< 
   /builders>
  </configBuilders>

<connectionStrings configBuilders="AzureKeyVault">
  <add name="ProductionConnstr" connectionString="from key vault" 
    providerName="System.Data.SqlClient" />
</connectionStrings>
Jashvita
  • 553
  • 3
  • 24

1 Answers1

1

We can make use of environment variables for different stages of environment and based on that we can invoke that particular keyvault created for each which has their own secrets. Lets say we Created app service app > made deployment slots for ex: dev,staging

enter image description here

  • We can make use of managed identity (Identity).

IDENTITY> SYSTEM ASSIGNED >ON for each slot which makes use of azure active directory to register apps to create client secrets separately for each which can be stored as secrets .

enter image description here

We can find the app and slots created in azure active directory enterprise applications when you search for all applictions and can make note of app id, client secret for each slot(dev,staging etc).

enter image description here

You can create keyvaults each one for dev and one for staging and others if required.

For the keyvault ,you can create access policies for environment slots you created for the app(ex: get ,list operations ) .

enter image description here

  • Create secrets like connection string ,clientsecret ,appid etc for dev and other environments.
  • You can add connection string for environment which will overwrite the local app settings .Refer:Managing Secrets-TechNet Wiki (microsoft.com)

Or

  • Create three settings files appsettings.production.json, appsettings.development.json,and other required environmentand appsettings.json .

You can override app settings and connection strings in the web.config using environment variables

 {
          "AzureKeyVault": {
             "Endpoint": "put KEYVAULT_ENDPOINT here",
             "ClientId": "XXXX ",
             "ClientSecret": "XXXXXX"
           //”ConnectionString”:"XXXXXXX”
           }
        }

In program.cs call the secrets for particular environment:

public static IHostBuilder CreateHostBuilder(string[] args) =>
             ....
            ....
.ConfigureAppConfiguration((hostBuilderContext, configurationBuilder) =>
            {
                
               ...//code
                    .AddJsonFile($"azurekeyvault.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", false, true);

                
                var configuration = configurationBuilder.Build();
                string keyVaultEndpoint = configuration["AzureKeyVault:Endpoint"];
                string clientId = configuration["AzureKeyVault:ClientId"];
             //string ConnectionString= configuration["AzureKeyVault: ConnectionString "];
                string clientSecret = configuration["AzureKeyVault:ClientSecret"];
           
              
                configurationBuilder.AddAzureKeyVault(keyVaultEndpoint, clientId, clientSecret);
            });

Please refer from this blog for more information.

(or) In each appsettings..json we can provide a vault uri of the particular environment vault.

“Vault Uri”:https://env-demo-keyvault.vault.azure.net/

Then call in program.cs file like below

var keyVaultEndpoint = settings["VaultUri"];

References:

  1. Azure key vault - add access policy for deployment slot - Stack Overflow
  2. Using Azure Key Vault with ASP.NET Core and Azure App Services
  3. ASP.NET Core + Azure Key Vault + Azure AD MSI-Joonas W's blog
kavyaS
  • 8,026
  • 1
  • 7
  • 19
  • Hi Kavya, I am back to this again. I have question. What is the purpose of program.cs code. Can you please explain what the code is trying to do. Also if I have multiple environment DEV, QA, Stage and prod then how at runtime one can figure out what is environment "ASPNETCORE_ENVIRONMENT". I am able to get the keyvault secret in web config file and able to make connection in dev and in prod environment but without changing the connectionstring. And I think you have removed the code to get the secret from the Azure keyVault. Much thanks – Jashvita Oct 01 '22 at 04:13