Feature management with Azure App Configuration

In modern software development where rapid release cycles often is preferred, you need to have some tools to reduce the risk related to new deployments. In an ideal world you would release your new features one at the time, at a steady predictable pace, but this isn’t the case for a lot of developers and organizations.

One of the tools to accommodate this, are feature flags. Implementing feature flags allows teams to operate at a higher pace, reduce risk, do testing at scale and have better control of their different environments. Having to deal with long lived feature branches as an alternative can be a real challenge as they tend to diverge and introduce complex merge situations with higher risk of issues once deployed.

Azure App Configuration is a service from Microsoft which has several useful tools in relation to operational excellence. If it’s the first time you hear about Azure App Configuration, check out my previous post which introduces the basic concepts and how to get started here 👉 The basics of Azure App Configuration

Feature manager

The feature manager in Azure App Configuration provide the management pane of feature flags in your applications. Start of by going to “Feature manager” in the left menu of your App Configuration instance.

From this view you can create two types of feature flags. A regular feature flag and a variant feature flag. A feature flag mainly consist of a name, and a status that tells us if the feature flag is enabled or disabled which can be utilized in your application. The flags also allows us to define criteria, like how high percentage of requests should get the enabled flag vs. how many should continue with old features. Moreover, it allows for precise targeting by specifying variants for individual users or groups, making it easy to exclude specific user segments from testing if needed.

When we take a look the the variant feature, it allows us to, as the name says – introduce different variants on a flag. This means that a flag can have multiple variant name which resolves to different values. Each variant can have different distribution like filtering on regular feature flags.

If we take a look at the filter of the new-blog-section feature you will see how the filters are configured.

Below you will se an example of my new-blog-section feature which has a 50% distribution, but with an override on specific users. Jeff, Alicia and Susan will get the feature enabled even if they fall outside of the default distribution. Based on these filters I get 4 disabled and 8 enabled.

Subsequent requests will maintain the same distribution, which makes sense so users doesn’t hop in and out of a set of features. So how is this done? Quite simply by building the targetcontext, and pass it along your IsEnabled check.

// Get user
User user = await userRepository.GetUser(userId);

// Build target context
var targetingContext = new TargetingContext
{
    UserId = user.Id,
    Groups = user.Groups
};

// Check if feature is enabled for user
bool enabled = await featureManager.IsEnabledAsync("new-blog-section", targetingContext);

We could also have filtered based on the Groups property if we had added a group filter in our Feature manager in Azure.

In terms of the user filtering the filters will be applied in the following execution flow:

Another cool feature of the feature manager is the ability to create custom filters. Custom filters is suited for developers who want to achieve more advanced filtering on feature flags, say you like to only enable features for certain browsers, or only for people in a specific country. This allows for highly targeted and dynamic feature rollouts, without complicating the application logic, which is nice.

When implementing this in your application you should also add the refresh capabilities of app configuration. This ensures that new features get picked up without needing to restart your app. You can do this using the IConfigurationRefresher and the TryRefreshAsync method. Keep in mind that feature flags are cached for 30 seconds, so you might need a couple of refreshes for changes to fully take effect.

Oh, and for those who spotted the Telemetry column in the feature manager screenshot. You can hook up telemetry using Application Insights to track how different feature variants perform. This gives you valuable insights into what’s working and what’s not.

Snapshots

Not directly part of the feature manager, but another useful tool in App Configuration is the possibility to do snapshots. Snapshots provide an isolated copy of the configuration of the time it was performed so you can rely on previously known good configurations.

Let’s say you have a large new feature or change that is going to be deployed which requires several configuration changes, then you can perform a snapshot to make sure that an potential rollback is easier to manage.

Snapshots can be referenced directly in the code, and due to their immutability you are sure that no changes will occur in your configuration that will cause a potential service disruption.

configurationBuilder.AddAzureAppConfiguration(options =>
{  
  options.Connect(Environment.GetEnvironmentVariable("ConnectionString"));
  options.SelectSnapshot("SnapshotName");
});

Using the SelectSnapshot method when configuring the service, will fill the configuration object with the values from the selected snapshot. By utilizing this method you can create specific snapshots for specific deploys and be sure that if something fails you can revert the reference to the old snapshot.

Hope you will test the service and have a good experience using it!


Posted

in

,

by

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *