AZ-204Chapter 55 of 102Objective 3.2

Feature Flags with Azure App Configuration

This chapter covers feature flags (also called feature toggles) and how to manage them using Azure App Configuration. Feature flags allow you to dynamically enable or disable application features without redeploying code, enabling safe experimentation, gradual rollouts, and instant kill switches. On the AZ-204 exam, this topic appears in roughly 5-8% of questions, primarily within the 'Implement secure cloud solutions' objective (3.2). You will be tested on how to define, store, and evaluate feature flags, use filters for targeted rollouts, and integrate with application code using the Feature Management library.

25 min read
Intermediate
Updated May 31, 2026

Feature Flags as Light Switches

Imagine a large office building with hundreds of light switches in a central control room. Each switch controls a specific light or group of lights (feature flags). The building manager (application) can flip any switch at any time without rewiring the building (redeploying code). The control room has a master panel (Azure App Configuration) that stores the state of every switch. When a worker (user) enters a room, the building manager checks the master panel to see if that light should be on or off. If the manager wants to test a new lighting scheme for a VIP visitor, they can turn on a special 'VIP mode' switch for just that visitor's badge (targeting filter). The manager can also schedule switches to turn on/off at specific times (time window filter). Importantly, the switches themselves are cheap and simple—they just indicate on/off—but the control room enables complex logic like 'turn on the blue lights for the marketing team but not for engineering.' This decouples the decision of which lights are on from the physical wiring, allowing rapid changes without electricians (developers) touching the building's infrastructure.

How It Actually Works

What Are Feature Flags and Why Do They Exist?

Feature flags (also known as feature toggles) are a software development technique that allows you to turn functionality on or off at runtime without deploying new code. Instead of using traditional if statements that are hardcoded, you wrap a feature in a conditional check against a configuration source. The flag's value (true/false) is stored externally—typically in Azure App Configuration—and can be changed on the fly. This decouples deployment from release: you can deploy code that is 'dark' (disabled) and later enable it for specific users or percentages.

The primary motivations for feature flags are: - Safe deployment: Roll out features gradually to catch issues early. - Targeted rollouts: Enable features for specific user segments (e.g., beta testers). - Instant kill switch: Disable a problematic feature immediately without rollback. - A/B testing: Run experiments with different feature states. - Environment-specific behavior: Enable debug features in dev, disable in prod.

How Azure App Configuration Stores Feature Flags

Azure App Configuration is a managed service that stores configuration key-value pairs and feature flags. Feature flags are stored as a special type of key-value with a prefix .appconfig.featureflag/. Each flag has: - ID: A unique identifier (e.g., "BetaSearch"). - Description: Optional human-readable text. - Enabled state: Boolean true/false. - Filters: An array of filter objects that determine when the flag is enabled for a given user/context.

Filters are evaluated at runtime. The most common filters are: - Percentage filter: Enables the feature for a random percentage of users (based on a user ID hash). - Time window filter: Enables the feature during a specific date/time range. - Targeting filter: Enables the feature for specific users, groups, or rollout percentages.

Under the hood, Azure App Configuration uses a REST API. When you create or update a feature flag via the portal, CLI, or SDK, it sends a PUT request to the store. The flag's JSON representation looks like:

{
  "id": "BetaSearch",
  "description": "Enable new search algorithm",
  "enabled": false,
  "conditions": {
    "client_filters": [
      {
        "name": "Microsoft.Targeting",
        "parameters": {
          "Audience": {
            "Users": ["user1@contoso.com"],
            "Groups": ["BetaTesters"],
            "DefaultRolloutPercentage": 10
          }
        }
      }
    ]
  }
}

The Feature Management Library

To consume feature flags in your application, you use the Microsoft.FeatureManagement library (for .NET) or equivalent libraries for other languages. This library provides: - IFeatureManager: Core interface to check if a feature is enabled. - IFeatureManagerSnapshot: Caches flag evaluations for the duration of a request (important for performance). - [FeatureGate] attribute: Allows declarative feature gating on controllers/actions.

How evaluation works: 1. Application calls await featureManager.IsEnabledAsync("BetaSearch"). 2. The library fetches the feature flag from Azure App Configuration (or local cache). 3. If the flag's enabled property is false, return false immediately (short-circuit). 4. If enabled is true, iterate through each filter in client_filters. 5. For each filter, call its Evaluate method with the context (user ID, etc.). 6. If any filter returns true, the feature is enabled; otherwise, it's disabled. 7. Results are cached according to the cache expiration setting (default 30 seconds).

Important: The enabled property acts as a master switch. If it's false, no filters are evaluated. If true, filters must also pass. This means you can have a flag that is globally enabled but filtered to only 10% of users.

Key Components, Values, and Defaults

Cache expiration: Default 30 seconds. Can be configured via CacheExpirationInterval in the AddAzureAppConfiguration options. Shorter intervals mean more calls to App Configuration (cost, latency).

Key prefix: Feature flags are stored with key prefix .appconfig.featureflag/. You should not manually create keys with this prefix.

Label: Feature flags support labels, allowing you to have different flag values per environment (e.g., label "dev" vs "prod").

Snapshot: IFeatureManagerSnapshot caches the evaluation for the lifetime of the request. Use this to avoid repeated calls within the same request.

Targeting filter parameters: Users, Groups, DefaultRolloutPercentage. The percentage is based on a hash of the user ID, ensuring consistent experience for the same user.

Configuration and Verification Commands

Azure CLI:

Create a feature flag:

az appconfig feature set --name myAppConfig --feature BetaSearch --description "New search" --enabled true

Add a targeting filter:

az appconfig feature filter add --name myAppConfig --feature BetaSearch --filter-name Microsoft.Targeting --parameters '{"Audience":{"Users":["alice@contoso.com"],"DefaultRolloutPercentage":25}}'

List all feature flags:

az appconfig feature list --name myAppConfig

Enable a flag:

az appconfig feature enable --name myAppConfig --feature BetaSearch

Portal: Navigate to your App Configuration resource, select "Feature manager" under Operations. You can create/edit/delete flags and add filters via the UI.

Verification: Use the portal's "Test" button to simulate a user ID and see if the flag would be enabled. Or use the CLI with az appconfig feature show to view the full JSON.

Integration with Application Code

In a .NET Core application, you register the feature management services in Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.AddAzureAppConfiguration()
        .Connect(Environment.GetEnvironmentVariable("ConnectionString"))
        .UseFeatureFlags();
    
    services.AddFeatureManagement();
}

Then use middleware to refresh configuration periodically:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseAzureAppConfiguration();
    // ...
}

In a controller:

[ApiController]
[Route("api/[controller]")]
public class SearchController : ControllerBase
{
    private readonly IFeatureManager _featureManager;

    public SearchController(IFeatureManager featureManager)
    {
        _featureManager = featureManager;
    }

    [HttpGet]
    public async Task<IActionResult> Get()
    {
        if (await _featureManager.IsEnabledAsync("BetaSearch"))
        {
            return Ok("New search results");
        }
        return Ok("Old search results");
    }
}

Or use the [FeatureGate] attribute:

[FeatureGate("BetaSearch")]
[HttpGet("new")]
public IActionResult NewSearch()
{
    return Ok("New search endpoint");
}

If the feature is disabled, the framework returns a 404 (NotFound) result automatically.

How It Interacts with Related Technologies

Azure App Configuration: The central store for feature flags. It supports multiple stores (e.g., different regions) and can be used with Key Vault references for secret values.

Azure Functions: Feature flags work in Functions as well. You inject IFeatureManager into your function class.

Azure DevOps: You can integrate feature flag changes into your CI/CD pipeline. For example, enable a flag after deployment validation.

Application Insights: Track which features are enabled for which users to monitor adoption and performance.

A/B Testing: Combine feature flags with Application Insights telemetry to measure user behavior under different flag states.

Performance Considerations

Caching: Always use IFeatureManagerSnapshot for request-scoped caching. Without it, each IsEnabledAsync call may hit the store or cache multiple times.

Latency: Azure App Configuration is designed for low latency (<10 ms for cached reads). However, network latency can add up if you don't cache.

Cost: Each read operation is metered. Frequent polling with short cache intervals increases cost. Default 30 seconds is a good balance.

Filter complexity: Complex filters (e.g., targeting with large user lists) are evaluated on the client side, not on the server. This reduces server load but requires sending user context.

Walk-Through

1

Define the feature flag

Decide on a unique feature flag name (e.g., 'NewCheckout'). Use Azure portal, CLI, or SDK to create the flag with initial state disabled. Set a description for documentation. The flag is stored as a key-value with prefix `.appconfig.featureflag/NewCheckout`. The default state is false. For the exam, remember that feature flags are not standard key-values; they have a special schema.

2

Configure filters for targeting

If you want gradual rollout, add a percentage filter with a rollout percentage (e.g., 25). For user-specific targeting, add a targeting filter with explicit user list or group. The percentage is based on a hash of the user ID (typically the authenticated user's object ID). The hash is consistent, so the same user always gets the same experience. Filters are evaluated in order; if any filter returns true, the feature is enabled.

3

Integrate Feature Management SDK

Add the `Microsoft.FeatureManagement.AspNetCore` NuGet package. In `Startup.ConfigureServices`, call `services.AddAzureAppConfiguration().Connect(connectionString).UseFeatureFlags()` and `services.AddFeatureManagement()`. This registers `IFeatureManager` and `IFeatureManagerSnapshot` in the DI container. The SDK will automatically poll App Configuration for changes every 30 seconds by default.

4

Gate code with feature flag checks

Use `IFeatureManager.IsEnabledAsync("NewCheckout")` in your business logic. For MVC controllers, you can use the `[FeatureGate("NewCheckout")]` attribute on actions. If the feature is disabled, the action returns 404. For Razor Pages, use the `FeatureGate` attribute on the page model. For conditional views, inject `IFeatureManager` and check in the view. Always use `IFeatureManagerSnapshot` for request-scoped caching to avoid repeated evaluations.

5

Test and monitor the rollout

Use the Azure portal's 'Test' feature to simulate a user ID and verify the flag evaluates as expected. Monitor Application Insights to see how many users are hitting the new feature. If issues arise, disable the flag immediately via portal or CLI. The change propagates within the cache expiration interval (default 30 seconds). For emergency kill switches, set cache expiration to a lower value (e.g., 5 seconds) during critical rollouts.

What This Looks Like on the Job

Enterprise Scenario 1: E-commerce Platform Gradual Rollout

A large e-commerce company wants to roll out a new recommendation engine to 10% of users initially. They create a feature flag NewRecommendations with a percentage filter set to 10. The user ID is the customer's email hash. The flag is stored in Azure App Configuration. The application checks the flag on every page load. After one week, they increase to 50%, then to 100% after monitoring conversion rates. If a bug is found, they disable the flag immediately. The team uses the Azure CLI for automation and integrates flag changes into their CI/CD pipeline via Azure DevOps. Performance is critical: they set cache expiration to 15 seconds to balance freshness and cost. They use IFeatureManagerSnapshot to avoid repeated calls within the same request.

Enterprise Scenario 2: Beta Program with Targeted Users

A SaaS provider wants to give beta access to specific enterprise customers. They create a feature flag BetaDashboard with a targeting filter that includes a list of user object IDs (from Azure AD) and a group "BetaTesters". The flag is enabled globally, but the filter restricts it to those users. They also set a default rollout percentage of 0 to ensure no one else sees it. The application uses the [FeatureGate] attribute on the beta dashboard controller. When a new customer signs up for beta, an admin adds their user ID to the targeting filter via the portal. The change takes effect within the cache interval. The team monitors usage via Application Insights and can disable the feature for a specific user by removing them from the list.

Common Pitfalls

Forgetting to call `UseAzureAppConfiguration()` middleware: Without it, configuration refresh doesn't happen, and flags may become stale.

Not using `IFeatureManagerSnapshot`: Developers inject IFeatureManager directly and call IsEnabledAsync multiple times in the same request, causing redundant evaluations.

Over-relying on percentage filter for small user bases: With few users, the percentage may not evenly distribute. Use targeting filter with explicit users for small groups.

Ignoring cache expiration: In emergency scenarios, 30-second delay can be too long. Set a lower cache expiration or use a separate 'kill switch' flag with no caching.

How AZ-204 Actually Tests This

What AZ-204 Tests on Feature Flags (Objective 3.2)

The exam focuses on implementing feature flags using Azure App Configuration and the Feature Management library. Specific sub-objectives include:

Creating and managing feature flags in App Configuration

Using filters (percentage, time window, targeting) to control rollout

Integrating feature flags into application code using IFeatureManager

Understanding caching behavior and refresh intervals

Differentiating between feature flags and standard configuration key-values

Common Wrong Answers and Why Candidates Choose Them

1.

Wrong: Feature flags are stored as standard key-values. Many candidates think feature flags are just another key-value pair. Reality: Feature flags have a special schema with conditions and filters, stored under the .appconfig.featureflag/ prefix.

2.

Wrong: The `enabled` property is the only control. Candidates assume that if enabled is true, the feature is on for everyone. Reality: Filters can override; if filters are present, they must also evaluate to true.

3.

Wrong: Filters are evaluated on the server. Some think Azure App Configuration evaluates filters. Reality: Filters are evaluated client-side by the Feature Management SDK. The store only returns the flag definition.

4.

Wrong: Cache expiration is not important. Candidates may ignore caching details. Reality: The exam tests that default cache expiration is 30 seconds and that IFeatureManagerSnapshot caches per request.

Specific Numbers and Terms to Memorize

Default cache expiration: 30 seconds

Feature flag key prefix: .appconfig.featureflag/

Filter names: Microsoft.Percentage, Microsoft.TimeWindow, Microsoft.Targeting

NuGet package: Microsoft.FeatureManagement.AspNetCore

Interface for snapshot: IFeatureManagerSnapshot

Attribute: [FeatureGate]

Method: IsEnabledAsync(string feature)

Edge Cases and Exceptions

Filter ordering: If a flag has multiple filters, they are evaluated in the order they appear in the JSON. If any filter returns true, the feature is enabled (OR logic).

Label usage: You can have different flag values per environment using labels. The exam may ask how to select a specific label.

Snapshot vs. regular: IFeatureManager may cache across requests; IFeatureManagerSnapshot caches only for the current request. Use snapshot when you need consistency within a single request.

How to Eliminate Wrong Answers

If the question mentions 'gradual rollout to 25% of users', look for 'percentage filter' or 'Microsoft.Percentage'.

If the question mentions 'enable only for specific users', look for 'targeting filter' or 'Microsoft.Targeting'.

If the question mentions 'enable during business hours', look for 'time window filter'.

If the question mentions 'without redeploying', it's about feature flags.

If the question mentions 'cached for 30 seconds', it's about default cache expiration.

Key Takeaways

Feature flags decouple deployment from release; you can enable/disable features without redeploying code.

Azure App Configuration stores feature flags under the `.appconfig.featureflag/` prefix with a structured JSON schema including conditions and filters.

The `Microsoft.FeatureManagement` library provides `IFeatureManager` and `IFeatureManagerSnapshot` for evaluating flags with client-side filter evaluation.

Default cache expiration is 30 seconds; use `IFeatureManagerSnapshot` for request-scoped caching.

Common filters: `Microsoft.Percentage` (gradual rollout), `Microsoft.Targeting` (user/group-based), `Microsoft.TimeWindow` (scheduled enablement).

The `[FeatureGate]` attribute can be used on controllers/actions to return 404 if the feature is disabled.

Changes to feature flags are not immediate due to caching; reduce cache expiration for faster propagation.

Always call `UseAzureAppConfiguration()` middleware to enable configuration refresh.

Easy to Mix Up

These come up on the exam all the time. Here's how to tell them apart.

Azure App Configuration Feature Flags

Supports filters (percentage, targeting, time window) for gradual rollout.

Uses the `IFeatureManager` SDK for evaluation and caching.

Stored under a special prefix with structured JSON.

Can be managed via portal, CLI, or SDK with dedicated feature flag commands.

Integrates with `[FeatureGate]` attribute for declarative gating.

Custom Configuration with Key-Values

No built-in filter support; you must implement your own logic.

You must manually read key-values and implement caching.

Stored as plain key-value pairs without schema.

Managed via generic key-value commands; no specialized UI.

Requires custom code for feature gating; no attribute support.

Watch Out for These

Mistake

Feature flags are just configuration key-values with a true/false value.

Correct

Feature flags have a structured schema with conditions and filters, stored under the `.appconfig.featureflag/` prefix. They are not plain key-values.

Mistake

The `enabled` property alone determines if a feature is on for all users.

Correct

If filters are present, the feature is enabled only if `enabled` is true AND at least one filter evaluates to true. The `enabled` property acts as a master switch.

Mistake

Filters are evaluated server-side by Azure App Configuration.

Correct

Filters are evaluated client-side by the Feature Management SDK in your application. The server only returns the flag definition.

Mistake

You can use any key-value pair as a feature flag by just reading its value.

Correct

Feature flags require the `Microsoft.FeatureManagement` library to properly evaluate filters and caching. Simply reading a key-value does not give you filter logic.

Mistake

Changes to feature flags take effect immediately.

Correct

Changes are picked up after the cache expiration interval (default 30 seconds). For immediate effect, you can reduce cache expiration or use a push-based refresh model.

Do You Actually Know This?

Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.

Frequently Asked Questions

How do I create a feature flag in Azure App Configuration?

You can create a feature flag via the Azure portal under 'Feature manager', or using the Azure CLI: `az appconfig feature set --name <store-name> --feature <flag-name> --enabled true`. The flag is stored with a special schema and prefix.

What is the difference between IFeatureManager and IFeatureManagerSnapshot?

`IFeatureManager` evaluates feature flags and may cache results across requests based on the configured cache expiration (default 30 seconds). `IFeatureManagerSnapshot` caches the evaluation for the duration of the current request only, ensuring consistent results within a single request. Use `IFeatureManagerSnapshot` when you need the same flag value throughout a request.

Can I use feature flags without the Feature Management library?

Technically, you can read the flag's key-value directly, but you lose filter evaluation, caching, and the `[FeatureGate]` attribute. The exam expects you to use the `Microsoft.FeatureManagement` library for proper integration.

How do I target specific users with a feature flag?

Add a targeting filter (`Microsoft.Targeting`) to the flag. In the filter parameters, specify an `Audience` object with `Users` (list of user IDs) and/or `Groups` (list of group names). You can also set a `DefaultRolloutPercentage` for users not explicitly listed.

How quickly do changes to a feature flag take effect?

By default, the Feature Management SDK polls Azure App Configuration every 30 seconds. So changes take up to 30 seconds to propagate. You can reduce the cache expiration interval in the `AddAzureAppConfiguration` options, but this increases cost and latency.

What is the purpose of the `[FeatureGate]` attribute?

The `[FeatureGate]` attribute can be applied to controller actions or Razor Pages. If the specified feature flag is disabled, the framework returns a 404 (NotFound) result. This provides a simple way to block access to entire endpoints without writing conditional code.

Can I have multiple feature flags that depend on each other?

The Feature Management library does not support built-in dependency between flags. You would need to check multiple flags in your code. However, you can use a single flag with complex filters to achieve similar results.

Terms Worth Knowing

Ready to put this to the test?

You've just covered Feature Flags with Azure App Configuration — now see how well it sticks with free AZ-204 practice questions. Full explanations included, no account needed.

Done with this chapter?