Zum Inhalt springen

Azure App Configuration integration

Dieser Inhalt ist noch nicht in deiner Sprache verfügbar.

Azure App Configuration logo

Azure App Configuration provides a service to centrally manage application settings and feature flags. Modern programs, especially programs running in a cloud, generally have many components that are distributed in nature. Spreading configuration settings across these components can lead to hard-to-troubleshoot errors during an application deployment. The Aspire Azure App Configuration integration enables you to connect to existing App Configuration instances or create new instances all from your AppHost.

The Aspire Azure App Configuration hosting integration models the App Configuration resource as the AzureAppConfigurationResource type. To access this type and APIs for expressing them within your AppHost project, install the 📦 Aspire.Hosting.Azure.AppConfiguration NuGet package:

Aspire CLI — Aspire.Hosting.Azure.AppConfiguration Paket hinzufügen
aspire add azure-appconfiguration

Die Aspire CLI ist interaktiv; das passende Suchergebnis wählen, wenn gefragt:

Aspire CLI — Beispielausgabe
Select an integration to add:
> azure-appconfiguration (Aspire.Hosting.Azure.AppConfiguration)
> Other results listed as selectable options...

To add an Azure App Configuration resource to your AppHost project, call the AddAzureAppConfiguration method providing a name:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var appConfig = builder.AddAzureAppConfiguration("config");
// After adding all resources, run the app...
builder.Build().Run();

When you add an AzureAppConfigurationResource to the AppHost, it exposes other useful APIs.

If you’re new to Bicep, it’s a domain-specific language for defining Azure resources. With Aspire, you don’t need to write Bicep by-hand, instead the provisioning APIs generate Bicep for you. When you publish your app, the generated Bicep is output alongside the manifest file. When you add an Azure App Configuration resource, the following Bicep is generated:

:::code language=“bicep” source=”../snippets/azure/AppHost/config/config.bicep”:::

Generated Bicep — config.bicep
@description('The location for the resource(s) to be deployed.')
param location string = resourceGroup().location
resource config 'Microsoft.AppConfiguration/configurationStores@2024-06-01' = {
name: take('config-${uniqueString(resourceGroup().id)}', 50)
location: location
properties: {
disableLocalAuth: true
}
sku: {
name: 'standard'
}
tags: {
'aspire-resource-name': 'config'
}
}
output appConfigEndpoint string = config.properties.endpoint
output name string = config.name

The preceding Bicep is a module that provisions an Azure App Configuration resource. Additionally, role assignments are created for the Azure resource in a separate module:

Generated Bicep — config-roles.bicep
@description('The location for the resource(s) to be deployed.')
param location string = resourceGroup().location
param config_outputs_name string
param principalType string
param principalId string
resource config 'Microsoft.AppConfiguration/configurationStores@2024-06-01' existing = {
name: config_outputs_name
}
resource config_AppConfigurationDataOwner 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(config.id, principalId, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5ae67dd6-50cb-40e7-96ff-dc2bfa4b606b'))
properties: {
principalId: principalId
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5ae67dd6-50cb-40e7-96ff-dc2bfa4b606b')
principalType: principalType
}
scope: config
}

The generated Bicep is a starting point and is influenced by changes to the provisioning infrastructure in C#. Customizations to the Bicep file directly will be overwritten, so make changes through the C# provisioning APIs to ensure they’re reflected in the generated files.

All Aspire Azure resources are subclasses of the AzureProvisioningResource type. This type enables the customization of the generated Bicep by providing a fluent API to configure the Azure resources—using the ConfigureInfrastructure API. For example, you can configure the sku, purge protection, and more. The following example demonstrates how to customize the Azure App Configuration resource:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
builder.AddAzureAppConfiguration("config")
.ConfigureInfrastructure(infra =>
{
var appConfigStore = infra.GetProvisionableResources()
.OfType<AppConfigurationStore>()
.Single();
appConfigStore.SkuName = "Free";
appConfigStore.EnablePurgeProtection = true;
appConfigStore.Tags.Add("ExampleKey", "Example value");
});

The preceding code:

  • Chains a call to the ConfigureInfrastructure API:
    • The infra parameter is an instance of the AzureResourceInfrastructure type.
    • The provisionable resources are retrieved by calling the GetProvisionableResources method.
    • The single AppConfigurationStore is retrieved.
    • The AppConfigurationStore.SkuName is assigned to Free.
    • A tag is added to the App Configuration store with a key of ExampleKey and a value of Example value.

There are many more configuration options available to customize the Azure App Configuration resource. For more information, see Azure.Provisioning customization.

Use existing Azure App Configuration resource

Section titled “Use existing Azure App Configuration resource”

You might have an existing Azure App Configuration store that you want to connect to. If you want to use an existing Azure App Configuration store, you can do so by calling the AsExisting method. This method accepts the config store and resource group names as parameters, and uses it to connect to the existing Azure App Configuration store resource.

var builder = DistributedApplication.CreateBuilder(args);
var configName = builder.AddParameter("configName");
var configResourceGroupName = builder.AddParameter("configResourceGroupName");
var appConfig = builder.AddAzureAppConfiguration("config")
.AsExisting(configName, configResourceGroupName);
// After adding all resources, run the app...
builder.Build().Run();

For more information, see Use existing Azure resources.

Connect to existing Azure App Configuration store

Section titled “Connect to existing Azure App Configuration store”

An alternative approach to using the *AsExisting APIs enables the addition of a connection string instead, where the AppHost uses configuration to resolve the connection information. To add a connection to an existing Azure App Configuration store, call the AddConnectionString method:

var builder = DistributedApplication.CreateBuilder(args);
var config = builder.AddConnectionString("config");
builder.AddProject<Projects.WebApplication>("web")
.WithReference(config);
// After adding all resources, run the app...

The connection string is configured in the AppHost’s configuration, typically under User Secrets, under the ConnectionStrings section. The AppHost injects this connection string as an environment variable into all dependent resources, for example:

{
"ConnectionStrings": {
"config": "https://{store_name}.azconfig.io"
}
}

The dependent resource can access the injected connection string by calling the GetConnectionString method, and passing the connection name as the parameter, in this case "config". The GetConnectionString API is shorthand for IConfiguration.GetSection("ConnectionStrings")[name].

Add Azure App Configuration emulator resource

Section titled “Add Azure App Configuration emulator resource”

Microsoft provides the Azure App Configuration emulator for developers who want a local, lightweight implementation of the Azure App Configuration service to code and test against. In Aspire, you can use this emulator by calling the RunAsEmulator method when you add your resource:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var appConfig = builder.AddAzureAppConfiguration("config")
.RunAsEmulator();
// After adding all resources, run the app...
builder.Build().Run();

The Azure App Configuration emulator isn’t installed on your local computer. Instead, it’s accessible to Aspire as a container. The RunAsEmulator method creates and starts the container when the AppHost starts using the azure-app-configuration/app-configuration-emulator image.

Configure Azure App Configuration emulator container

Section titled “Configure Azure App Configuration emulator container”

There are various configurations available to container resources. For example, you can configure the container’s port, environment variables, its lifetime, and more.

Configure Azure App Configuration emulator host port
Section titled “Configure Azure App Configuration emulator host port”

By default, Aspire assigns a random host port for the emulator container. If you want to use a specific port, chain calls on the container resource builder provided by the RunAsEmulator method as shown in the following example:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var appConfig = builder.AddAzureAppConfiguration("config")
.RunAsEmulator(emulator =>
{
emulator.WithHostPort(28000);
});
// After adding all resources, run the app...

The preceding code configures the emulator container’s endpoint to listen on port 28000.

Configure Azure App Configuration emulator with persistent lifetime
Section titled “Configure Azure App Configuration emulator with persistent lifetime”

To configure the emulator container with a persistent lifetime, call the WithLifetime method on the emulator container resource and pass ContainerLifetime.Persistent:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var appConfig = builder.AddAzureAppConfiguration("config")
.RunAsEmulator(emulator =>
{
emulator.WithLifetime(ContainerLifetime.Persistent);
});
// After adding all resources, run the app...
Configure Azure App Configuration emulator with data volume
Section titled “Configure Azure App Configuration emulator with data volume”

By default, the Azure App Configuration emulator doesn’t persist data between container restarts. To enable persistent storage using a Docker volume, call the WithDataVolume method on the emulator resource:

var builder = DistributedApplication.CreateBuilder(args);
var appConfig = builder.AddAzureAppConfiguration("config")
.RunAsEmulator(emulator =>
{
emulator.WithDataVolume();
});
// After adding all resources, run the app...

The data volume is used to persist the emulator data outside the lifecycle of its container, ensuring configuration values survive container restarts. The data volume is mounted at the /data path in the emulator container and when a name parameter isn’t provided, the name is autogenerated from the application and resource names (for example, if your application is named myapp and the resource is config, the autogenerated name will be myapp-config). For more information on data volumes and details on why they’re preferred over bind mounts, see Docker docs: Volumes.

Configure Azure App Configuration emulator with data bind mount
Section titled “Configure Azure App Configuration emulator with data bind mount”

To persist emulator data to a specific directory on your host machine, call the WithDataBindMount method. This is useful when you want direct access to the data files on your host system:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var appConfig = builder.AddAzureAppConfiguration("config")
.RunAsEmulator(emulator =>
{
emulator.WithDataBindMount("../Emulator/Data");
});
// After adding all resources, run the app...

Data bind mounts rely on the host machine’s filesystem to persist the emulator data across container restarts. The data bind mount is mounted at the ../Emulator/Data path on the host machine relative to the AppHost directory (IDistributedApplicationBuilder.AppHostDirectory) in the emulator container. For more information on data bind mounts, see Docker docs: Bind mounts.

To get started with the Aspire Azure App Configuration client integration, install the 📦 Aspire.Microsoft.Extensions.Configuration.AzureAppConfiguration NuGet package in the client-consuming project, that is, the project for the application that uses the App Configuration client. The App Configuration client integration registers an Azure configuration provider to populate the IConfiguration instance.

.NET CLI — Add Aspire.Microsoft.Extensions.Configuration.AzureAppConfiguration package
dotnet add package Aspire.Microsoft.Extensions.Configuration.AzureAppConfiguration

In the Program.cs file of your client-consuming project, call the AddAzureAppConfiguration extension method on any IHostApplicationBuilder to register the required services to flow Azure App Configuration values into the IConfiguration instance for use via the dependency injection container. The method takes a connection name parameter.

C# — Program.cs
builder.AddAzureAppConfiguration(connectionName: "config");

You can then retrieve the IConfiguration instance using dependency injection. For example, to retrieve the client from an example service:

C# — ExampleService.cs
public class ExampleService(IConfiguration configuration)
{
private readonly string _someValue = configuration["SomeKey"];
}

Configure the Azure App Configuration provider

Section titled “Configure the Azure App Configuration provider”

The AddAzureAppConfiguration method accepts an optional Action<AzureAppConfigurationOptions> configureOptions delegate that you use to configure the Azure App Configuration provider. This follows the same pattern as the non-Aspire Microsoft.Extensions.Configuration.AzureAppConfiguration package, but Aspire automatically handles the connection—you don’t need to call options.Connect.

C# — Program.cs
builder.AddAzureAppConfiguration(
"config",
configureOptions: options =>
{
// Select specific keys or labels
options.Select("MyApp:*");
options.Select("MyApp:*", "Production");
// Configure refresh options
options.ConfigureRefresh(refresh =>
{
refresh.Register("MyApp:Sentinel", refreshAll: true)
.SetRefreshInterval(TimeSpan.FromSeconds(30));
});
});

For more information on available configuration options, see the Azure App Configuration provider reference.

To use feature flags, install the 📦 Microsoft.FeatureManagement NuGet package:

.NET CLI — Add Microsoft.FeatureManagement package
dotnet add package Microsoft.FeatureManagement

App Configuration doesn’t load feature flags by default. To load feature flags, use the configureOptions delegate (as shown in Configure the Azure App Configuration provider) to call UseFeatureFlags() when calling builder.AddAzureAppConfiguration.

C# — Program.cs
builder.AddAzureAppConfiguration(
"config",
configureOptions: options => options.UseFeatureFlags());
// Register feature management services
builder.Services.AddFeatureManagement();

The configureOptions pattern is used to configure the Azure App Configuration provider. For more information, see Azure App Configuration: .NET configuration provider. You can then use IFeatureManager to evaluate feature flags in your app. Consider the following example ASP.NET Core Minimal API app:

C# — Program.cs
using Microsoft.Extensions.Hosting;
using Microsoft.FeatureManagement;
var builder = WebApplication.CreateBuilder(args);
builder.AddAzureAppConfiguration(
"config",
configureOptions: options => options.UseFeatureFlags());
// Register feature management services
builder.Services.AddFeatureManagement();
var app = builder.Build();
app.MapGet("/", async (IFeatureManager featureManager) =>
{
if (await featureManager.IsEnabledAsync("NewFeature"))
{
return Results.Ok("New feature is enabled!");
}
return Results.Ok("Using standard implementation.");
});
app.Run();

For more information, see .NET Feature Management.

The Aspire Azure App Configuration library provides multiple options to configure the Azure App Configuration connection based on the requirements and conventions of your project. The App Config endpoint is required to be supplied, either in AzureAppConfigurationSettings.Endpoint or using a connection string.

When using a connection string from the ConnectionStrings configuration section, you can provide the name of the connection string when calling builder.AddAzureAppConfiguration():

C# — Program.cs
builder.AddAzureAppConfiguration("config");

Then the App Configuration endpoint is retrieved from the ConnectionStrings configuration section. The App Configuration store URI works with the AzureAppConfigurationSettings.Credential property to establish a connection. If no credential is configured, the DefaultAzureCredential is used.

JSON — appsettings.json
{
"ConnectionStrings": {
"config": "https://{store_name}.azconfig.io"
}
}

The Aspire Azure App Configuration library supports Microsoft.Extensions.Configuration. It loads the AzureAppConfigurationSettings from configuration by using the Aspire:Microsoft:Extensions:Configuration:AzureAppConfiguration key. Example appsettings.json that configures some of the options:

JSON — appsettings.json
{
"Aspire": {
"Microsoft": {
"Extensions": {
"Configuration": {
"AzureAppConfiguration": {
"Endpoint": "YOUR_APPCONFIGURATION_ENDPOINT_URI"
}
}
}
}
}
}

For the complete App Configuration client integration JSON schema, see ConfigurationSchema.json.

You can also pass the Action<AzureAppConfigurationSettings> configureSettings delegate to set up some or all the options inline, for example to set App Configuration endpoint from code:

C# — Program.cs
builder.AddAzureAppConfiguration(
"config",
configureSettings: settings => settings.Endpoint = "https://YOUR_URI");

The Aspire Azure App Configuration integration uses the following log categories:

  • Microsoft.Extensions.Configuration.AzureAppConfiguration.Refresh

The Aspire Azure App Configuration integration doesn’t make use of any activity sources thus no tracing is available.

The Aspire Azure App Configuration integration currently doesn’t support metrics.

Fragen & AntwortenZusammenarbeitenCommunityDiskutierenAnsehen