Configure Applications with App Configuration and Key Vault
The Azure Key Vault provides a great service to store application secrets and use them to configure your applications; however, with relatively low limits some applications referencing Key Vault with a lot of secrets or even clustered applications referencing fewer secrets can get rate limited and experience slow startup performance. You should instead use Azure App Configuration to store non-secrets and define references to secrets in Key Vault to reduce the number of calls made to Key Vault.
Examples of non-secrets that should be stored in App Configuration:
- Client application IDs
- IP addresses
- Service endpoints
- Service configuration parameters
- Usernames
Examples of secrets that should be stored in Key Vault:
- Client application secrets
- Connection strings
- Passwords
- Shared access keys
- SSH keys
Getting started
To build and run this sample you will need:
Software:
Azure services:
(Optional) App Service - needed to deploy the web application to Azure, which is provisioned in the Bicep template.
Note
App Service has support for referencing Key Vault secrets directly, but is used only as an example how to configure a web site to use App Configuration. If you choose to deploy your web application to another service, the same principles to configure the App Configuration connection string still apply.
(Optional) Application Insights - to monitor web traffic and application traces, which is not provisioned in the Bicep template.
To deploy the template manually, make sure your Azure CLI is up to date and run:
az bicep install # if deploying azuredeploy.bicep
az group create --location {location} --resource-group {group-name}
az deployment group create --resource-group {group-name} --template-file azuredeploy.bicep # or azuredeploy.json
There are a number of parameters you can optional set. View the template for details.
After deployment completes, make note of the output variables as shown in the example below:
{
"outputs": {
"appConfigConnectionString": {
"type": "String",
"value": "Endpoint=https://{appconfig-host-name}.azconfig.io;Id={id};Secret={secret}"
},
"siteUrl": {
"type": "String",
"value": "https://{site-host-name}.azurewebsites.net/"
},
"vaultUrl": {
"type": "String",
"value": "https://{vault-host-name}.vault.azure.net/"
}
}
}
Building the sample
You can build, run, and even deploy the sample using Visual Studio, Visual Studio Code, or the .NET command line interface (CLI). Using the dotnet
CLI, for example, within the directory containing the sample application source run:
dotnet build
Running the sample
Before you can run the sample locally you'll need to grant access to the Key Vault for your local user account or service principal. If you're logged into your tenant in Visual Studio and the Azure CLI using the same principal, you can find the UPN or SPN the same way:
az account show
If you're logged in as a user, you will see your email address and can pass that to the --upn
parameter:
az keyvault set-policy -n {vault-host-name} --upn {user@domain.com} --secret-permissions get
If you're logged in as a service principal, the user.type
will be servicePrincipal
and you'll pass the the user.name
to the --spn
parameter:
az keyvault set-policy -n {vault-host-name} --spn {spn} --secret-permissions get
Next you'll need to add the App Configuration connection string from the template deployment outputs to your local user secrets:
Right-click on the project
Click Managed User Secrets
Add a variable named
ConnectionStrings:AppConfig
with thevalue
of theappConfigurationConnectionString
output variable:{ "ConnectionStrings:AppConfig": "Endpoint=https://{appconfig-host-name}.azconfig.io;Id={id};Secret={secret}" }
Click Debug -> Start debugging (F5) to run.
Deploying the sample
See the ASP.NET quickstart for instructions to deploy for Visual Studio, Visual Studio Code, and the dotnet
CLI. For Visual Studio and Visual Studio Code, make sure you select your existing resource if you deployed the Bicep template above; otherwise, for the dotnet
CLI you can deploy to an existing resource by configuring Git support and pushing source, which will be built automatically on the host.
Configuring App Configuration with Key Vault references
Using Azure App Configuration is an efficient way to store application configuration key-value pairs, and can reference Key Vault secrets. The App Configuration service itself doesn't need access to these secrets, but your application - like the sample web application here - will need nothing more than get
access to Key Vault secrets. Configuration in ASP.NET enumerates key-value pairs from a number of configured providers, which not only requires both list
and get
permissions to Key Vault but is the main cause of application startup performance problems or even failures. By using the Microsoft.Extensions.Configuration.AzureAppConfiguration package you can reduce the calls to Key Vault while the package itself will automatically fetch secrets' values as needed.
Add the following package to your project:
dotnet add package Azure.Identity dotnet add package Microsoft.Extensions.Configuration.AzureAppConfiguration
At the top of Program.cs (or wherever your entry point is defined) add the following
using
statements:using Azure.Identity; using Microsoft.Extensions.Configuration;
Update the
CreateHostBuilder
method to call theConfigureAppConfiguration
extension method as shown below:public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.ConfigureAppConfiguration(config => { var settings = config.Build(); var connectionString = settings.GetConnectionString("AppConfig"); config.AddAzureAppConfiguration(options => { options.Connect(connectionString); options.ConfigureKeyVault(options => { options.SetCredential(new DefaultAzureCredential()); }); }); }) .UseStartup<Startup>(); });
This uses the ConnectionStrings:AppConfig
defined within the deployed web application or locally in your user secrets to connect to Azure App Configuration. Whenever a referenced secret is enumerated, the configuration provider will automatically retrieve it using the DefaultAzureCredential
that is designed to work optimally in both development and production environments without code changes. When running from the deployed web application, the web application's system identity is used to connect to Key Vault. When running locally, a number of your local credentials are attempted including your Visual Studio, Visual Studio Code, and Azure CLI credentials. If you see an error message that your local application is not authorized for the deployed Key Vault, see our troubleshooting section for help.
Caching clients
You can also reduce the number of calls to Azure Key Vault by caching your SecretClient
or any other Key Vault SDK client. Our clients are designed to reuse an HttpClient
by default and cache authentication bearer tokens for service like Key Vault to reduce the number of calls to authenticate. You can use our Microsoft.Extensions.Azure to cache clients and use them elsewhere:
public void ConfigureServices(IServiceCollection services)
{
services.AddAzureClients(config =>
{
config.UseCredential(new DefaultAzureCredential());
// Assumes the deployed Key Vault URL is stored in a variable named KEYVAULT_URL.
config.AddSecretClient(new Uri(Configuration["KEYVAULT_URL"]));
});
services.AddRazorPages();
}
In ASP.NET Razor pages as an example, you can then inject them into the page:
@using Azure.Security.KeyVault.Secrets;
@inject SecretClient SecretClient
<p>Connected to @SecretClient.VaultUri</p>