Feature Flags: Concepts to Implementation

What Are Feature Flags?

Feature flags (also known as feature toggles or feature switches) are a powerful software development technique that allows teams to modify system behavior without changing code. At their core, they are conditional statements that determine whether a feature is visible to users or how it behaves.

Toggle features on/off without code deploys

Feature flags decouple feature releases from code deployment, allowing you to remotely enable or disable functionality without pushing new code.

Enable gradual rollouts, A/B testing, and quick rollbacks

Roll out features to a small percentage of users initially, compare versions, and instantly revert problematic features without emergency fixes.

Decouple deployment from release

Deploy code to production while keeping features hidden until they’re ready for public use, allowing for better testing in production environments.

Feature flags enable teams to implement trunk-based development more effectively by hiding incomplete features behind toggles. This separates the technical act of deployment from the business decision to release, giving teams more control over the user experience.

No Feature Flags? Chaos.

Risky Deployments

Every deployment is an all-or-nothing gamble, making new features immediately visible to all users and escalating the impact of bugs or performance issues. This leads to higher stress, increased downtime for rollbacks, and a larger blast radius for any problems.

Development Bottlenecks

Long-running feature branches cause painful merge conflicts and delay integration feedback. Teams face pressure to rush features or delay releases, leading to slower release cycles and delayed integration testing.

Limited Testing Options

Validating solely in pre-production misses crucial real-world conditions. Without feature flags, safely confirming new functionality in a live production environment is difficult, leading to disparities and limited real user feedback.

Business Stakeholder Limitations

Business users are dependent on developers for every change in feature access or rollout strategy. This lack of control, limits experimentation and slows down the response to dynamic market needs.

These challenges create a high-friction environment that slows innovation and increases risk, making it harder to deliver value quickly and reliably to customers.

Why Use Feature Flags?

Feature flags transform how teams approach software delivery by providing fine-grained control over feature availability. They bridge the gap between development agility and operational stability.

Reduce Risk of New Releases

Implement dark launches and canary releases to test features with limited exposure. Instantly disable problematic features without emergency code deployments.

Test in Production Safely

Validate features in real-world conditions while controlling who sees them. Get accurate performance metrics and user feedback before full release.

Target Features to Specific Users

Roll out features to beta testers, premium customers, or specific regions. Create personalized experiences based on user attributes or behaviors.

Improve Continuous Delivery Velocity

Deploy incomplete features to production behind flags. Adopt trunk-based development with shorter-lived branches and fewer merge conflicts.

By separating deployment from release, feature flags create a safer, more controlled environment for innovation while maintaining system stability. This control extends across the entire software delivery lifecycle, from development to operations to business decision-making.

Types of Feature Flags

Feature flags serve different purposes throughout your application lifecycle. Understanding these distinctions helps determine appropriate implementation strategies and lifecycle management approaches.

Release Toggles

Control the timing and audience for feature rollouts. These flags typically have a short lifespan and should be removed once a feature is fully released.

Example: Gradually enabling a new checkout flow to 10%, then 50%, then 100% of users.

Experiment Toggles

Enable A/B testing to compare different implementations or designs. These flags exist for the duration of the experiment and are removed once conclusions are drawn.

Example: Testing multiple pricing displays to see which drives more conversions.

Ops Toggles

Provide operational control over system behavior. These are often long-lived and give operations teams the ability to manage system stability.

Example: Disabling resource-intensive features during peak load times.

Permission Toggles

Control feature access based on user roles or attributes. These flags tend to be permanent parts of the codebase supporting multi-tier access.

Example: Showing admin features only to users with administrative permissions.

Release Toggles: Unlocking Controlled Rollouts

Release toggles are temporary feature flags designed to manage the launch of new features safely and effectively.

Gradual Rollouts

Release features to a small percentage of users, slowly increasing exposure while monitoring performance and user feedback for stability.

Dark Launches

Deploy new code to production with the feature disabled by default, allowing for real-world testing without exposing it to end-users.

Targeted Releases

Activate features for specific user segments, like internal teams, beta testers, or premium customers, based on their attributes or roles.

By using these types of release toggles, teams can de-risk deployments, gather valuable insights, and deliver new capabilities with confidence.

Experiment Toggles: Driving Data-Backed Decisions

Experiment toggles are pivotal for data-driven product development, allowing teams to rigorously test hypotheses and gather insights directly from user interactions.

A/B Testing

Compare two versions of a feature or UI element to determine which performs better against a defined metric, such as conversion rates or engagement.

Multivariate Testing

Evaluate the impact of multiple changes simultaneously by testing various combinations of elements to identify optimal designs and user flows.

User Segmentation Experiments

Test different experiences or feature sets on distinct user segments to understand preferences and tailor offerings more effectively.

By leveraging experiment toggles, organizations can continuously optimize user experiences, validate product changes, and confidently make decisions based on real-world performance.

Ops Toggles: Ensuring Operational Stability

Ops toggles are long-lived feature flags crucial for managing the operational aspects of an application, allowing teams to maintain stability and control in dynamic environments.

Kill Switches & Circuit Breakers

Quickly disable features or entire sections of an application that are causing issues (e.g., bugs, performance bottlenecks) without requiring a new deployment.

Example: Instantly turn off a new payment gateway integration if it’s experiencing widespread failures during peak hours.

Maintenance Mode Toggles

Control the application’s state during planned maintenance windows, major deployments, or unexpected outages, often by redirecting users or displaying informative messages.

Example: Activate a “system undergoing maintenance” page for all users while database upgrades are being performed.

Configuration & Environment Toggles

Adjust application behavior or switch between different service providers/configurations in various environments (development, staging, production) without code changes.

Example: Toggle between a test email service and a production email service depending on the environment, or adjust logging verbosity.

By providing real-time control over system functionality, ops toggles empower operations teams to respond swiftly to incidents, manage system health, and ensure continuous service availability.

Permission Toggles: Controlling Access and Entitlements

Permission toggles are long-lived feature flags that enable precise control over user access to features, content, or application functionalities based on defined criteria.

Role-Based Access (RBAC)

Manage access to features by associating them with predefined user roles. This ensures different user types (e.g., admin, editor, viewer) see and interact with only relevant parts of the application.

Example: Only users with the ‘Administrator’ role can access system configuration panels.

Attribute-Based Access

Grant or restrict feature access based on dynamic user attributes like subscription tier, geographical location, or specific group membership. This provides fine-grained control and personalization.

Example: ‘Premium’ subscribers unlock advanced analytics dashboards, while basic users do not.

Licensing & Entitlement Control

Activate or deactivate modules and functionalities within the application based on purchased licenses or specific entitlements. This is crucial for product monetization and tiered offerings.

Example: A specific integration is only available to users who have purchased the ‘Enterprise’ plan add-on.

By embedding permission toggles, organizations can dynamically manage user experiences, enforce business rules, and ensure features are only exposed to their intended audiences, without needing code deployments.

Feature Flag Challenges & Best Practices

Avoid Feature Flag Debt

Feature flags can quickly accumulate and complicate your codebase if not managed properly.

  • Document each flag’s purpose and expected lifespan
  • Schedule regular “flag cleanup days” as part of your sprint cycle
  • Add expiration dates to temporary flags to force review

Secure Flag Management

Feature flags can represent significant business logic and need proper security controls.

  • Implement role-based access control for flag management
  • Audit flag changes to track who modified what and when
  • Separate production flag access from development environments

Establish Naming Conventions

Consistent naming makes flags easier to understand and manage at scale.

  • Use prefixes to denote flag type (e.g., “release.”, “exp.”, “perm.”)
  • Include feature area (e.g., “checkout.newFlow”)
  • Document naming standards in your team wiki

Monitoring Best Practices

Comprehensive monitoring is essential for understanding feature flag impact:

  • Track flag evaluation counts and performance impact
  • Monitor business metrics before and after flag changes
  • Set up alerts for unexpected behavior after flag state changes
  • Use distributed tracing to understand flag effects across services

Remember that feature flags introduce conditional branches in your code, which can create additional complexity. This complexity must be managed through good practices and tooling to realize the full benefits of feature flags.

Serving Up Feature Flags with Azure App Configuration

Azure App Configuration is a fully managed service that provides a centralized store for application settings and feature flags. It simplifies configuration management across multiple environments, regions, and applications.

Centralized Configuration

Store all application settings, connection strings, and feature flags in a single, secure location. Reduce configuration sprawl across multiple services and environments.

Dynamic Updates

Push configuration changes to applications in real-time without redeployment. Applications can subscribe to changes using the App Configuration SDK.

Azure Integration

Seamlessly works with Azure Key Vault, Azure DevOps, Azure Functions, and other Azure services. Leverage existing authentication mechanisms.

.NET Native Support

First-class integration with .NET applications through Microsoft.FeatureManagement libraries. Minimal code changes required for implementation.

Key Benefits for .NET Teams

  • Minimal code changes required to implement feature flags
  • Consistent implementation across microservices
  • Role-based access control for flag management
  • Configuration snapshots for point-in-time recovery
  • Native integration with Azure pipelines for automated flag management
  • Cost-effective pricing based on configuration storage and operations

Azure App Configuration provides a robust platform for implementing feature flags with minimal infrastructure overhead, making it an ideal choice for .NET teams already working within the Azure ecosystem.

Azure App Configuration Feature Flags Overview

Azure App Configuration’s feature manager provides a comprehensive feature flag system with advanced targeting capabilities. It stores feature flags as key-value pairs with special attributes and prefixes that the Feature Management library recognizes.

Simple and Variant Flags

Create boolean on/off flags or multi-variant flags that return different values based on conditions. Variants can return strings, numbers, or complex JSON objects.

Environment Labels

Use labels to manage different flag configurations per environment (dev, test, prod). Labels create isolated configuration views without duplicating keys.

Feature Filters

Apply conditional targeting based on user groups, time windows, percentages, or custom rules. Built-in filters include:

  • Microsoft.Targeting (user/group targeting)
  • Microsoft.TimeWindow (date/time control)
  • Microsoft.Percentage (gradual rollout)

History and Versioning

Track changes to feature flags over time with point-in-time snapshots. Roll back to previous configurations if issues arise. Compare configurations across revisions.

The Feature Management library makes it easy to evaluate these flags in your .NET code, handling the complexity of filter evaluation while providing a clean API for developers.

Creating Feature Flags in Azure Portal

Azure App Configuration provides an intuitive UI for creating and managing feature flags. Let’s walk through the process of setting up a new feature flag in the Azure portal.

Access your App Configuration store in the Azure portal. Select “Feature manager” from the left navigation menu, then click “Create” to add a new feature flag.

Define Flag Properties

Enter a unique key (e.g., “Beta.NewCheckout”), add an optional description, and set the flag state (enabled/disabled). Use standard naming conventions for consistency.

Configure Targeting Rules

Add feature filters to control flag evaluation. For example, you might target specific user groups or limit the flag to a time window during a planned marketing event.

Add Labels (Optional)

Apply environment-specific labels like “dev” or “prod” to maintain different configurations across environments using the same key.

Save and Monitor

Save the feature flag and monitor its usage through Azure metrics. You can track flag evaluation counts and modify the flag as needed based on performance or business requirements.

Example: Creating a Targeted Feature Flag

Let’s create a feature flag that enables a new reporting dashboard only for users in the “Analytics” group during business hours:

  1. Key: feature.enhancedReporting
  2. Description: “Enhanced reporting dashboard with real-time analytics”
  3. Enable: Yes
  4. Add filter: Microsoft.Targeting
  5. Configure groups: “Analytics” with 100% rollout
  6. Add filter: Microsoft.TimeWindow
  7. Configure time: Monday-Friday, 8:00-18:00

This configuration ensures that the new reporting feature is only available to the appropriate users during business hours when support staff are available to assist with any issues.

WARNING: This is for understanding and experimentation. All Azure resources, including App Configurations, should be created programmatically through Infrastructure-as-Code, such as with Terraform (coming up)!

Variant Feature Flags

While boolean feature flags (on/off) are useful for many scenarios, variant feature flags provide more flexibility by allowing multiple possible values. This enables more sophisticated targeting and experimentation scenarios.

Key Capabilities

  • Define multiple discrete variants beyond simple on/off
  • Assign different probabilities to each variant
  • Return complex objects like configuration settings
  • Combine with targeting rules for sophisticated control
  • Implement A/B/n testing with multiple variants

Using Feature Flags in .NET Applications

Implementation Steps

1. Install NuGet Packages

Install the appropriate Azure App Configuration and Feature Management NuGet packages. These packages provide the essential components for integrating Azure App Configuration and enabling feature flag evaluation within your application.

2. Configure Azure App Configuration

Connect your application to Azure App Configuration and configure it to load feature flags. Adjust the cache expiration interval as needed for dynamic updates.

3. Add Feature Management to Services

Register the Feature Management services in your application’s Startup.cs or Program.cs. Include specific feature filters if you plan to use targeting based on time, percentage, or other custom criteria.

4. Integrate App Configuration Middleware

Using Feature Flags in Code

Once configured, feature flags can be consumed in various parts of your .NET application:

1. Dependency Injection with IFeatureManager

Inject IFeatureManager into your services or controllers to programmatically check the status of a feature flag.

2. Using FeatureGate Attributes

Apply [FeatureGate] attributes to controllers or actions to automatically enable or disable routes based on feature flag states. This attribute can also define complex requirements.

3. In Razor Views

Managing Feature Flags with Other Languages

Azure App Configuration provides flexible ways to manage feature flags across various programming languages, allowing you to implement feature management in your existing application stacks.

Python

Access feature flags through the Azure App Configuration client library for Python and apply logic as needed.

Java (Spring)

Integrate using Spring Cloud Azure’s feature management module for seamless usage with Spring Boot applications.

JavaScript/Node.js

Utilize the Azure App Configuration client library to fetch feature flag values and implement conditional logic.

While the core concepts remain similar, the specific implementation details and library availability vary by language, leveraging language-idiomatic approaches for configuration and feature management.

Managing Feature Flags with Terraform

Terraform enables infrastructure as code for your feature flags, allowing version control, automated deployment, and consistency across environments. Here’s how to manage Azure App Configuration feature flags with Terraform.

# Create Azure App Configuration resource
resource "azurerm_app_configuration" "appconf" {
  name                = "myappconfig"
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location
  sku                 = "standard"
}

# Create a simple feature flag
resource "azurerm_app_configuration_feature" "new_ui" {
  configuration_store_id = azurerm_app_configuration.appconf.id
  description            = "Enables the new UI experience"
  name                   = "NewUI"
  enabled                = true
}

# Create a feature flag with targeting
resource "azurerm_app_configuration_feature" "beta_feature" {
  configuration_store_id = azurerm_app_configuration.appconf.id
  description            = "Beta feature for testing"
  name                   = "BetaFeature"
  enabled                = true

  feature_filter {
    name = "Microsoft.Targeting"
    parameters_json = jsonencode({
      "Audience": {
        "Users": ["user1@example.com", "user2@example.com"],
        "Groups": ["BetaTesters"],
        "DefaultRolloutPercentage": 0
      }
    })
  }
}

Using Feature Flags in Azure DevOps Pipelines

Integrating feature flags into your Azure DevOps pipelines enables powerful control over your infrastructure and application deployments, allowing you to decouple code releases from feature activation. This approach supports progressive rollouts, A/B testing, and controlled dark launches for changes, including schema updates or new resource deployments.

Define Flag in Azure App Configuration

Establish your feature flag in Azure App Configuration, configuring its initial state (on/off) and any targeting filters (e.g., users, groups, percentages).

Access Flag in Pipeline

Utilize the “Azure App Configuration” task in your Azure DevOps pipeline to retrieve the feature flag’s value, making it available as a pipeline variable.

Conditional Deployment Logic

Apply pipeline conditions to stages or tasks. For example, conditionally deploy a DACPAC update based on the feature flag’s state.

Controlled Activation

The infrastructure change is deployed but remains inactive until the feature flag is toggled on in Azure App Configuration, enabling precise control over its release to users.

This method provides a robust mechanism to test infrastructure changes safely in production environments before exposing them widely, reducing deployment risk significantly.

Testing with Feature Flags

Feature flags introduce unique considerations for quality assurance (QA) teams, expanding the scope of testing and requiring adaptable strategies to maintain product quality and accelerate development cycles.

Manual QA Considerations

  • Test flag states (on/off): Every new feature controlled by a flag must be tested in both its enabled and disabled states to confirm correct behavior and graceful fallback.
  • Verify combinations of multiple flags: When multiple flags interact, the number of possible test scenarios can explode. Testers need to identify critical flag combinations that might lead to unexpected interactions or bugs.
  • Expanded test matrix for each release: The need to test various flag states and their combinations inherently leads to a larger, more complex test matrix that requires meticulous tracking and execution.
  • Clear documentation for flag states: Testers rely heavily on up-to-date documentation that outlines each feature flag’s purpose, states, and dependencies to conduct effective testing.

Automated Testing Considerations

Automated testing becomes even more critical with feature flags to manage the increased complexity and ensure rapid feedback on changes.

  • Run end-to-end tests for critical flag states: Key user flows and business-critical functionalities should have automated end-to-end tests that run against both the feature-on and feature-off configurations.
  • Mock feature flags for isolated unit tests: For unit and integration tests, feature flag services can be mocked or faked to isolate the component under test and simulate various flag states without external dependencies.
  • Parameterize tests based on flag configurations: Design automated tests to be configurable, allowing them to be run easily with different feature flag values passed in as parameters.
  • Dedicated test environments for specific flag combinations: For complex scenarios, it may be beneficial to provision temporary test environments that are pre-configured with specific feature flag combinations to thoroughly test unique interactions.

Best Practices for Testing with Feature Flags

Automate Heavily

Prioritize automated tests across various flag configurations, including unit, integration, end-to-end, and UI tests. Automation efficiently manages complexity, provides rapid feedback, and supports faster release cycles.

Flag Hygiene

Regularly audit and remove obsolete or unused feature flags from your codebase and configuration store. Stale flags increase technical debt, complicate testing, and introduce potential security risks. Implement a clear deprecation process.

Clear Naming and Documentation

Implement consistent and descriptive naming conventions for all feature flags to avoid confusion and ensure maintainability. Maintain comprehensive documentation detailing each flag’s lifecycle, dependencies, and expected behavior.

Strategies for Managing Test Complexity

To navigate the intricacies of feature flag testing, consider these additional strategies:

Tagging & Categorization

Group related feature flags and features to focus testing efforts on specific areas impacted by changes, streamlining test plans and reducing cognitive load.

Branching Strategies

Align feature flag strategies with your branching model, moving towards trunk-based development where flags control primary releases, simplifying testing.

Continuous Integration

Integrate feature flag tests directly into your CI/CD pipeline, ensuring every code commit is automatically validated against critical flag configurations to catch issues early.

A/B Test Monitoring

For experiment flags, integrate comprehensive monitoring and analytics to validate the impact of the new feature on user behavior and key business metrics once it’s live.

Empowering Business Users with Feature Flag Control

Enabling product managers and business stakeholders to control feature flags directly accelerates experimentation and reduces developer bottlenecks.

Custom Admin Portals

Develop a tailored web interface that interacts with Azure App Configuration APIs. This provides a simplified, role-based experience designed specifically for non-technical users, abstracting away technical complexities. This could be folded into existing UIs if available. The API could update Azure App Configurations through the Azure API.

Automated Deployment Pipelines

Create parameterized Azure DevOps pipelines that business users can trigger. These pipelines can update feature flag states in Azure App Configuration, allowing controlled rollouts and rollbacks without direct portal access. These pipelines could run Terraform to keep everything infrastructure-as-code friendly.

Direct Updates Through Azure Portal

Business users can directly update application settings through the Azure Portal’s App Configuration service. For proper governance, administrators should implement fine-grained access permissions to ensure users can only modify specific configuration values relevant to their role.

Create A REST API

With a carefully crafted backend REST API service, anything can be hooked up to it. It can even be made available to customers to implement with their own user interfaces, or even automated. The sky is the limit.

Best Practices for Feature Flag Management

Effective feature flag management is crucial for development teams to maximize their benefits while minimizing technical debt and operational overhead. Adhering to these best practices ensures a smooth, secure, and efficient lifecycle for your flags, from creation to cleanup, empowering rapid experimentation and controlled deployments.

Define Flag Lifecycles

Establish clear processes for flag creation, activation, deprecation, and eventual removal. Regularly review and remove stale flags to prevent technical clutter and reduce complexity.

Assign Ownership & Document

Assign a clear owner for each feature flag to manage its lifecycle, monitoring, and impact. Maintain documentation detailing its purpose and rollout strategy.

Integrate with CI/CD Pipelines

Automate feature flag changes within CI/CD pipelines. This ensures flags are consistently managed alongside code deployments, enabling safe rollouts, rollbacks, and A/B tests.

Implement Granular Targeting

Leverage granular targeting capabilities (e.g., users, groups, percentages) to control feature exposure. This enables safe, incremental rollouts and facilitates A/B testing or dark launches.

Monitor Performance & Impact

Continuously monitor performance and user experience metrics when a feature flag is active. This helps quickly identify any regressions or negative impacts.

Develop a Robust Rollback Plan

For every feature flag, have a clear and tested rollback strategy. This includes knowing how to quickly disable a feature or activate a kill switch in case of unexpected issues.

Manage Technical Debt & Flag Cleanup

Proactively identify and remove obsolete feature flags to prevent technical debt and reduce code complexity. Regularly scheduled flag cleanup ensures a lean and maintainable codebase.

Implement Strict Access Control

Enforce role-based access control (RBAC) to ensure only authorized personnel can modify feature flag states. This prevents accidental changes and enhances security.

Need Help?

VergeOps has partnered with dozens of Fortune 500 companies to help them drive speed and innovation through making strategic improvements in AI, DevOps, Platform Engineering, Test Automation, and Enterprise Architecture.

We can help your organization use feature flags in your applications. Contact us today to discuss how we can help.