In the first part, an overview of the External Configuration Store Pattern and the Azure Configuration Service was provided. In this part, an implementation using the Azure Configuration Service will be given.

You can view the complete implementation in my GitHub Repository .

In the code example, we will store the logging settings of multiple Azure services in the Azure Configuration Service. It will demonstrate how these services update their settings when changes occur.

Creating the Azure Configuration Service Link to heading

First, we create the Azure Configuration Service. To do this, open a PowerShell and select the Azure subscription in which the Config Service should be created.

$global:AzResourceGroupName="AppConfigResource-rg"
$global:AzAppConfigName="AppConfigResource-config"

# Create the test resource group
az group create --name $global:AzResourceGroupName --location westeurope
# Create the Azure App Config Store
az appconfig create --location centralus --name $global:AzAppConfigName --resource-group $global:AzResourceGroupName

Write-Host "Created application configuration service " $global:AzAppConfigName

az appconfig kv set --name $global:AzAppConfigName --key Logging:LogLevel:Default --value Information --yes
Write-Host "Added key to " $global:AzAppConfigName

# Get the connection string
az appconfig credential list --name $global:AzAppConfigName

The script shown above creates a resource group with an Azure Configuration Service. Then, it creates the logging setting as a key in the Azure Configuration Service. At the end of the script, the connection string to the Azure Configuration Service is displayed. This will be needed later.

Creating an ASP NET Core API Link to heading

In the next step, we create an ASP.NET Core Web API that uses the Azure Configuration Service. To do this, we create the .NET project and add the NuGet package for the Azure Configuration Service.

$serviceName = "myservice"
dotnet new webapi --output $serviceName
cd $serviceName
dotnet add package Microsoft.Azure.AppConfiguration.AspNetCore

Next, we open the created project with our IDE. The next step is to provide the connection string to the created .NET project. To do this, open the appsettings.json file and add the following lines:

"ConnectionStrings": {
    "AppConfig": "..."
  }

For the value of the ConnectionString, use the connection string from the section Creating the Azure Configuration Service.

In the next step, we open Program.cs. There, we insert the following startup code:

            ...
            builder.Services.AddEndpointsApiExplorer();
            builder.Services.AddSwaggerGen();

            // Load configuration from Azure App Configuration
            string connectionString = config.GetConnectionString("AppConfig");

            config.AddAzureAppConfiguration(options =>
            {
                options.Connect(connectionString)
                       // Load all keys that start with `Logging:` and have no label
                       .Select($"Logging:{KeyFilter.Any}", LabelFilter.Null)
                       // Configure to reload configuration if the registered sentinel key is modified
                       .ConfigureRefresh(refreshOptions =>
                            refreshOptions.Register("Logging:LogLevel:Default", LabelFilter.Null, refreshAll: true)
                                          .SetCacheExpiration(TimeSpan.FromSeconds(3)));
            });
            services.AddAzureAppConfiguration();

            ...

            if (app.Environment.IsDevelopment())
            {
                app.UseSwagger();
                app.UseSwaggerUI();
            }
            // Add the following line, for getting notified, when the sentinel key has changed
            app.UseAzureAppConfiguration();

            ...

Here is a description of the code:

First, the connection string to the Azure App Configuration is retrieved from the application configuration named “AppConfig”.

Then the Azure App Configuration is configured using the AddAzureAppConfiguration() method. Options are defined to establish a connection to the specified Azure App Configuration and to load configuration data. It is also defined that all keys that begin with “Logging:” and do not have a label should be loaded. It is also configured that the configuration is updated when the registered sentinel key (“Logging:LogLevel:Default”) is changed. This is achieved with the ConfigureRefresh() method, which sets a cache expiry time of 3 seconds for the configuration data.

The Azure App Configuration services are added to the service collection to make them available in the application.

The middleware UseAzureAppConfiguration() is registered. This middleware ensures that the application is notified when the configuration changes, especially when the sentinel key is changed.

To summarize, this code snippet uses Azure App Configuration to load and automatically update configuration data when changes are made. The middleware UseAzureAppConfiguration() is used to ensure that the application is notified of configuration changes.

Translated with DeepL.com (free version)

First Tests Link to heading

Now it’s time to test. We can now start the application. The application should start without errors. If the service is started now, the configurations are also loaded from the Azure Configuration Service. The service should now log every HTTP request normally in the LogLevel Information. Now switch to your Powershell and execute the following command:

az appconfig kv set --name $global:AzAppConfigName --key Logging:LogLevel:Default --value Warning --yes

You have now set the LogLevel Warning. If you now send further requests against your API, no log message should be logged.

Further thoughts Link to heading

Using the example shown, we can centrally manage configurations of various services.

Structure of sentinel keys Link to heading

A “sentinel key” is a concept used in configuration management to detect changes in the configuration and trigger the update of the application configuration.

In terms of the code above, a sentinel key is used to monitor if the configuration changes and the application needs to be updated. If this key is changed in the Azure App Configuration, this triggers the update of the application configuration.

In the example code, the sentinel key is set as “Logging:LogLevel:Default”. If this key changes in the Azure App Configuration, the configuration is automatically reloaded to reflect the changes.

For a distributed application, it makes sense to consider the structure of the sentinel key.

Selecting the refresh interval Link to heading

The refresh interval for updating the configuration depends on the requirements of your application. Some factors that should be considered are:

  • Frequency of configuration changes: How often are changes to the configuration expected? If the configuration is relatively stable and is rarely changed, a longer refresh interval might be sufficient. On the other hand, if the configuration is changed frequently, a shorter interval may be required to ensure that the application is always using the most up-to-date settings.

  • Effects of configuration changes: How much do configuration changes affect the way your application works? If changes to the configuration need to have an immediate impact, a shorter refresh interval is required to ensure that the application responds quickly to these changes.

  • Performance: Refreshing the configuration more frequently can lead to a higher load on the configuration servers as well as higher CPU utilization and network load on the part of the application. Therefore, the refresh interval must be chosen to provide an appropriate balance between timeliness and performance.

Some common refresh intervals can range from seconds to minutes, depending on the factors mentioned above. An interval of a few seconds to a few minutes is typical, but it is important to decide this based on the specific requirements of your application and possibly validate through testing.