External Configuration Store Pattern
Problem
Need to share configuration settings accross multiple applications : exemple include DB connection strings, UI theme info, URLs of queue, etc.
Simplify and centralize the changes to configuration schemas when updates to apps and components.
Solution
Store the configuration information in external storage, and provide an interface that can be used to quickly and efficiently read and update configuration settings.
Include multiple versions of the configuration (dev, staging, production, … and versioning).
static void Main(string[] args)
{
// Start monitoring configuration changes.
ExternalConfiguration.Instance.StartMonitor();
// Get a setting.
var setting = ExternalConfiguration.Instance.GetAppSetting("someSettingKey");
…
}
External Configuration Store in Practice
In Azure, we can use Azure App Configuration and combine the latter with Azure Key Vault : Azure App Configuration supports key-value pairs that can be namespaced.
Azure App Configuration provides a service to centrally manage application settings and feature flags.
Example of code with Azure Function in C# : FunctionApp Isolated Mode
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.FeatureManagement;
using System;
namespace FunctionAppIsolatedMode
{
public class Program
{
public static void Main()
{
var host = new HostBuilder()
.ConfigureAppConfiguration(builder =>
{
builder.AddAzureAppConfiguration(options =>
{
options.Connect(Environment.GetEnvironmentVariable("ConnectionString"))
// Load all keys that start with `TestApp:` and have no label
.Select("TestApp:*")
// Configure to reload configuration if the registered key 'TestApp:Settings:Sentinel' is modified.
// Use the default cache expiration of 30 seconds. It can be overriden via AzureAppConfigurationRefreshOptions.SetCacheExpiration.
.ConfigureRefresh(refreshOptions =>
{
refreshOptions.Register("TestApp:Settings:Sentinel", refreshAll: true);
})
// Load all feature flags with no label. To load specific feature flags and labels, set via FeatureFlagOptions.Select.
// Use the default cache expiration of 30 seconds. It can be overriden via FeatureFlagOptions.CacheExpirationInterval.
.UseFeatureFlags();
});
})
.ConfigureServices(services =>
{
// Make Azure App Configuration services and feature manager available through dependency injection
services.AddAzureAppConfiguration()
.AddFeatureManagement();
})
.ConfigureFunctionsWorkerDefaults(app =>
{
// Use Azure App Configuration middleware for data refresh
app.UseAzureAppConfiguration();
})
.Build();
host.Run();
}
}
}