Azure App Configuration : Refresh Configuration Dynamically

We have seen how can we use the Azure configuration store and connect our .Net 5 API app with it if you are not familiar with it please go through this article. Now in this article let’s try to explore how can we leverage the ability of the Azure App configuration to refresh the configuration dynamically.

.Net Core provides various configuration providers which can read the data from files, Environment variables or some in-memory configuration, Azure App configuration provider as well . one of the good things about this provider is they are capable of handling the changes without causing the application to restart.

.Net core provides the ways to create the strongly typed .Net classes. We can use IOptionSnapShot<T> which we can use to automatically load the configuration whenever the changes in the structure occur.

In this tutorial let’s explore how can we set up the dynamic updates to the configuration for the Azure App configuration store for the app which we have created in the previous article.

So first step in implementing this flow will be to set up the key and then reload the configuration after a specific interval.

  1. Add Sentinel ( Watch) Key

So Now question what Sentinel Key is? What it does? Why it is called a sentinel Key: To summarise, the Sentinel key is a special key that is updated after updating the keys in the application.

Meanwhile, our application will be Nick Fury which will keep monitoring this sentinel key for any changes

Nick Fury

This approach makes sure that we have consistent propagation of the configuration across the application and also it reduces the number of attempts made to the Azure app configuration store to load the configuration values. as compared to registering and monitoring all the keys for the change .so will this be a special key or configuration in the App configuration store? The answer is No it will be a simple key without any labels or any special thing so let’s just see how do we add this key in the application

Adding Sentinel Key

The above image shows all the things needed for adding the sentinel key

Refresh data from Azure configuration store

Now once we have set up the configuration and sentinel key in the store, it’s time to configure our application to read the key and reload the configuration based on that.

Install NuGet packages

The first step to get the things going on here is to install the Azure App configuration package which can be done like below

dotnet add package Microsoft.Azure.AppConfiguration.AspNetCore

Add Secrets using Secret Manager

dotnet user-secrets init
dotnet user-secrets set "ConnectionStrings:AzureAppConfigurationEndPoint" "Your App Configuration Connection string"

Change in Program. cs and HostBuilder

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using System;

namespace AzureAppConfigurationDemo
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                webBuilder.ConfigureAppConfiguration(AddAppConfigFromAzure).UseStartup<Startup>());

        private static void AddAppConfigFromAzure(IConfigurationBuilder config)
        {
            var appSettings = config.Build();
            var azureConfigStoreConnection = appSettings.GetConnectionString("AzureAppConfigurationEndPoint");

            config.AddAzureAppConfiguration(_=>
            {
                _.Connect(azureConfigStoreConnection).ConfigureRefresh(r =>
                    r.Register("AzureAppDemo:Sentinel", refreshAll: true).SetCacheExpiration(TimeSpan.FromSeconds(60)));

            });
        }
    }
}

In the above section, if we look at the AddAppConfigFromAzure() we will pick up the app configuration connection string which is set at the user secrets and then from that we will register the Azure app configuration in the store.

Once we have registered the azure configuration store next is to ConfigureRefresh() to set up the sentinel and monitor the changes in the configuration, It Registers the key which we want to monitor, the second parameter that it accepts is the refreshAll which tells to refresh all the keys in the configuration. SetCacheExpiration() is the method that accepts the interval in which the new request is made to the app configuration to reload and refresh the configuration.

In our case we will monitor the key AzureAppDemo: Sentinel and we will refresh all the keys in the application whenever the change in the sentinel key is observed, also with the SetCacheExpiration() what we are doing is just setting the Time interval at which our application will send a request and check the key for the change.

Ok now we have set up the keys and interval but where does the refresh trigger happen how do we make sure that it will be triggered automatically. the answer is the AppConfiguration middleware so let’s check how can we set up the middleware and what changes we need.

Adding AppConfiguration middleware

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;

namespace AzureAppConfigurationDemo
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddAzureAppConfiguration()
                    .AddSwaggerGen(c =>    c.SwaggerDoc("v1", new OpenApiInfo { Title = "AzureApp Configuration Demo", Version = "v1" }))
                    .AddControllers();


        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseAzureAppConfiguration();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseSwagger();
                app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "AzureAppConfigurationDemo v1"));
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}

In the above code snippet, we can see two methods Configure() and ConfigureServices() which are used for adding the middlewares and registering the dependencies in the application respectively, now we need to update the Configure() method and add a call to the UseAzureAppConfiguration() method. This will enable the application to handle the configuration updates for us automatically at regular intervals.

Now how does this whole flow works lets try to summarize it?

  1. The midleware monitors the key we have registered in the host builder while adding the Azure configuration store , it checks for the key which we have registered in the confiugureRefresh() while building the configuration.
  2. The middleware triggered on every incoming requests , but the call to the azure configuration store is only made when the cache expiration time is elapsed.
  3. when the change is detected it updates the all configuration values or the registered conffiguration values are refreshed .
  4. Now if for some reason our request to the app configuration store fails we will have the cached version which is already present and another check to the store will be made when the cached duration is elapsed.
  5. In order to make sure that our configuration is refreshed properly make sure that we have added our call to app.UseAzureAppConfiguration(); at appropriate place .

Now we have seen how we can configure the sentinel key, how can we make sure that configuration is refreshed properly using middleware now let’s check the output and how the configuration values will be changed.

For this let’s run our application and perform the following steps.

First, let’s run the application and open the swagger. let’s execute our action and we will see the values which are already present. now let’s change the values at the App configuration store, in this process keep in mind when we change the values let’s change the value of the sentinel key as well. once these values are changed let’s again call the API once the cache period is elapsed that we can observe that our values are refreshed and new configuration values are loaded again.

This was how we can dynamically and automatically refresh the configuration values without restarting the application.

References

https://docs.microsoft.com/en-us/azure/azure-app-configuration/enable-dynamic-configuration-aspnet-core?tabs=core5x

https://github.com/Azure/AppConfiguration/issues/448

https://k2vacademy.com/2020/02/02/centralized-configuration-management-using-azure-app-configuration-setting-up-dynamic-refresh-for-configuration-values/

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s