Configuration sprawl is a quiet tax: settings duplicated across app service settings, YAML files, and pipeline variables, with “which value is production actually using” a genuine research question. Azure App Configuration centralizes it, and its feature flag engine turns deployment and release into separate events, which is the capability that changes how teams ship.
Configuration as a Service
The store holds key values with labels as the dimension axis: the same key carries values labeled dev, test, prod, and applications load their label at startup, ending the per environment file forks. Key Vault references keep the boundary this series drew, secrets live in Key Vault, App Configuration holds pointers, and the application resolves both through one provider with its managed identity, so config and secrets arrive through one code path with two storage tiers of appropriate hardening. Snapshots capture an immutable, named set of keys, deploy against the snapshot and every instance sees identical configuration regardless of concurrent edits, which converts “config drift between instances during a rollout” from a debugging story into an impossibility. Dynamic refresh completes it: a sentinel key watched by the provider, bump it and instances reload changed settings without restart within their poll interval, giving operations a lever that does not require a deployment, with the audit trail the activity log provides.
builder.Configuration.AddAzureAppConfiguration(options =>
{
options.Connect(new Uri(appConfigEndpoint), new DefaultAzureCredential())
.Select(KeyFilter.Any, "prod")
.ConfigureKeyVault(kv => kv.SetCredential(new DefaultAzureCredential()))
.ConfigureRefresh(refresh =>
refresh.Register("sentinel", refreshAll: true)
.SetRefreshInterval(TimeSpan.FromSeconds(30)))
.UseFeatureFlags();
});
Feature Flags and Progressive Release
The feature management layer stores flags with filters, and filters are where the value concentrates. The percentage filter releases to a fraction of traffic; the targeting filter releases to named users and groups with a percentage default, which composes into the canonical rollout: internal team first, then five percent, then fifty, then everyone, moving between stages by editing the flag, not redeploying, and rolling back a misbehaving feature in seconds by the same edit. The discipline that keeps flags from becoming the new sprawl: every flag has an owner and an intended removal date (a flag past its date is tech debt with a toggle), flags gate behavior, not configuration values (settings belong to the config half), and flag checks concentrate at boundaries, a handler, a service facade, rather than scattering through business logic until nobody can enumerate the states. Pair rollout stages with the observability from yesterday, error rate and latency split by flag state, and progressive delivery gets its feedback loop; the deployment strategies from the Container Apps and DevOps posts handle the binary, flags handle the behavior, and together releases stop being events and become dials.
Running It
Standard tier for production, private endpoint and Entra auth with RBAC data plane roles (reader for workloads, owner for pipelines), per the invariant pattern. Geo replication adds read replicas in other regions with the provider failing over automatically, cheap resilience for a service on the startup path of everything. Import the store’s content from the repo through the pipeline so configuration changes are pull requests with review, reserving portal edits for the operational flags whose whole point is speed, and even those land in the audit log. One store per environment boundary or one with labels is a legitimate either; what is not legitimate, after this post, is configuration whose location, history, and blast radius nobody can name.
Cheers
Osama
Leave a Reply