← Back to all posts

Azure App Configuration in .NET

Azure App Configuration in .NET

Reading Time: 5 minutes

The Problem

Application configuration starts simple and then gets messy fast.

At first, a single appsettings.json file feels good enough. Then the system grows:

  • different values are needed for local, test, staging, and production
  • multiple services need the same settings
  • secrets are separated into Key Vault, but non-secret settings are still duplicated everywhere
  • operations teams need to change configuration without redeploying an app
  • developers lose track of which value is actually active in which environment

The result is configuration sprawl. Values are copied across JSON files, deployment pipelines, environment variables, and internal runbooks. The application still works, but understanding configuration becomes harder than writing the code that uses it.

The Solution

Azure App Configuration gives you a central store for non-secret application settings, with features designed for modern distributed systems.

It helps by providing:

  • a single place for shared application configuration
  • labels for environment or version-specific values
  • integration with ASP.NET Core configuration providers
  • optional refresh support so applications can react to changes
  • tight integration with Azure Key Vault for secret references

The practical model is straightforward:

  • store normal configuration values in Azure App Configuration
  • keep secrets in Key Vault
  • load both into a .NET application through the standard configuration system
  • use managed identity and DefaultAzureCredential instead of connection strings where possible

What Belongs in App Configuration

Azure App Configuration is best for values such as:

  • service endpoints
  • UI or API behavior toggles that are not feature flags
  • retry settings and timeouts
  • cache durations
  • queue or topic names
  • environment-specific application settings

It is not the right home for secrets like:

  • API keys
  • database passwords
  • client secrets
  • signing credentials

Those should stay in Azure Key Vault, even if App Configuration references them.

Labels and Organization

One of the most useful features in App Configuration is the label.

A key can exist multiple times with different labels:

  • null or empty label for defaults
  • Development
  • Staging
  • Production

This means you can keep the same logical key but vary the value by environment without duplicating entire config files.

A common pattern is:

  • load unlabeled defaults first
  • load environment-specific labels second
  • let environment-specific values override the defaults

.NET Setup

Install the packages:

dotnet add package Microsoft.Extensions.Configuration.AzureAppConfiguration
dotnet add package Azure.Identity

Add the App Configuration endpoint to appsettings.json:

{
  "AzureAppConfiguration": {
    "Endpoint": "https://your-app-config.azconfig.io"
  }
}

Create an options class:

public sealed class AzureAppConfigurationOptions
{
    public const string SectionName = "AzureAppConfiguration";

    public string Endpoint { get; set; } = string.Empty;
}

Loading App Configuration in ASP.NET Core

The cleanest approach is to extend the configuration pipeline in Program.cs.

using Azure.Identity;

var builder = WebApplication.CreateBuilder(args);

var appConfigEndpoint = builder.Configuration["AzureAppConfiguration:Endpoint"];

if (!string.IsNullOrWhiteSpace(appConfigEndpoint))
{
    builder.Configuration.AddAzureAppConfiguration(options =>
    {
        options.Connect(new Uri(appConfigEndpoint), new DefaultAzureCredential())
            .Select("*", LabelFilter.Null)
            .Select("*", builder.Environment.EnvironmentName);
    });
}

This does a few important things:

  • uses DefaultAzureCredential so the same code works locally and in Azure
  • loads unlabeled defaults first
  • loads environment-specific keys second
  • keeps configuration access aligned with the standard .NET configuration model

Binding Strongly Typed Options

Once the provider is in place, the rest looks exactly like normal ASP.NET Core configuration.

public sealed class PaymentsOptions
{
    public const string SectionName = "Payments";

    public string BaseUrl { get; set; } = string.Empty;
    public int TimeoutSeconds { get; set; } = 30;
    public int MaxRetries { get; set; } = 3;
}
builder.Services
    .AddOptions<PaymentsOptions>()
    .Bind(builder.Configuration.GetSection(PaymentsOptions.SectionName));
using Microsoft.Extensions.Options;

public sealed class PaymentsClient
{
    private readonly PaymentsOptions _options;

    public PaymentsClient(IOptions<PaymentsOptions> options)
    {
        _options = options.Value;
    }

    public Uri GetBaseUri() => new(_options.BaseUrl);
}

That is one of the main benefits of App Configuration: your application code does not need to know where the values came from.

Refreshing Configuration at Runtime

If you want an application to respond to changed configuration without restarting, App Configuration supports refresh.

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

var builder = WebApplication.CreateBuilder(args);

var endpoint = builder.Configuration["AzureAppConfiguration:Endpoint"];

if (!string.IsNullOrWhiteSpace(endpoint))
{
    builder.Configuration.AddAzureAppConfiguration(options =>
    {
        options.Connect(new Uri(endpoint), new DefaultAzureCredential())
            .Select("*", LabelFilter.Null)
            .Select("*", builder.Environment.EnvironmentName)
            .ConfigureRefresh(refreshOptions =>
            {
                refreshOptions.Register("App:Sentinel", refreshAll: true)
                              .SetRefreshInterval(TimeSpan.FromMinutes(5));
            });
    });

    builder.Services.AddAzureAppConfiguration();
}

var app = builder.Build();

app.UseAzureAppConfiguration();

A common pattern is using a sentinel key such as App:Sentinel. When that key changes, the app refreshes all registered configuration. This avoids refreshing the entire configuration set on every small change check.

Key Vault References

App Configuration works especially well with Key Vault references.

That gives you a split of responsibilities:

  • App Configuration stores the application setting structure
  • Key Vault stores the secret value

For example:

  • Payments:BaseUrl from App Configuration
  • Payments:ApiKey from Key Vault via a reference

This keeps secrets out of App Configuration while still centralizing how configuration is wired together.

Security Model

The recommended access model is:

  • use managed identity for Azure-hosted workloads
  • use DefaultAzureCredential for local development and Azure runtime
  • grant the application only the permissions it needs on App Configuration and Key Vault
  • avoid connection strings where identity-based access is available

That usually means:

  • App Configuration Data Reader for reading settings
  • Key Vault Secrets User for reading referenced secrets

Practical Recommendations

A strong default approach looks like this:

  • keep defaults under the null label
  • use labels for environment-specific overrides
  • use strongly typed options in application code
  • use a sentinel key for refresh instead of refreshing everything constantly
  • keep secrets in Key Vault, not App Configuration
  • authenticate with managed identity and DefaultAzureCredential

Summary

Azure App Configuration solves a real scaling problem in modern applications: configuration should be centralized, understandable, and changeable without turning deployment into archaeology.

In .NET, it integrates cleanly with the existing configuration system, which means you get the benefit without changing how your application code consumes settings.

The most pragmatic pattern is:

  • App Configuration for normal settings
  • Key Vault for secrets
  • labels for environment-specific values
  • managed identity for access
  • strongly typed options for application code

That gives you cleaner configuration management without scattering values across every environment and service.

References