fast, safe and forward only Continuously deploy to production Never roll back in production Fine-tune the user experience and functionality in production
of repository branches Simple form of switching functionality on and off Other reasons include Testing in production Flighting Instant kill switch Selective activation for user bases
Existing logic There might not be an original feature Original feature Program flow If statement evaluates state of feature flag First always off New feature Incomplete feature can be still be deployed
code • Time release • Performance related • Manual circuit breakers • Testing scenarios • Dynamic • Targeted users • Defining cohorts Short-lived Short to long-lived Short lived User or request based • On • Off • Percentage • On/Off Kill-switch • Percentage • Time Window • Claims • Cookies • Tenant
Might be more intricate than binary state Externalized to decouple from application Application Logic Feature toggle Management UI Feature Service Rules Settings Evaluates and filters on certain conditions Determines flag state Multiple parameters
parameters for complex evaluation Different per environment Feature Value Feature Value Feature Value Chatbot On Chatbot On Chatbot Off APIv2 Parameters APIv2 Off APIv2 Off BetaWebsite On BetaWebsite On BetaWebsite Opt-in Development Testing Acceptance Production
change during running Filters for evaluation (on/off, custom) Externalized storage of key/value pairs Cache and refresh plus ability to vary per environment Separated management and data planes
a Service Microsoft .NET Feature Management Also available for .NET Framework, Java Spring, JavaScript, Python, Node and Go (2020) Esquio (2022) Platform as a Service Azure App Configuration RimDev.AspNetCore.FeatureFlags (2022) Feature Switcher (Apache 2.0, 2018) Feature Toggle (Apache 2.0, 2017) FlipIt (Apache 2.0, 2012) NFeature (GPL, 2012)
are available Application logic FeatureManager service Calls IsEnabledAsync Feature management is injected in application logic reads .NET configuration Might be a cached snapshot or refreshed
EvaluateAsync(FeatureFilterEvaluationContext context); } Provided out of the box 1 3 PercentageFilter TimeWindow 2 4 TargetingFilter AlwaysOn Other (custom) filters: User targeted, e.g. ClaimsFilter, CookieFilter, BrowserFilter
revisions Feature flags Integration with Application Insights Regular Azure things Networking Geo replication RBAC and IAM Backup and delete protection Key/Value pairs Feature flags Management UI Tooling CLI and libraries
builder.AddAzureAppConfiguration("appconfig") .RunAsEmulator(emulator => { emulator.WithHostPort(28000); emulator.WithDataVolume(); emulator.WithLifetime(ContainerLifetime.Persistent); }); Name Resource name and connection string var webApp = builder.AddProject<Projects.WebApp>("webapp", launchProfileName) .WithExternalHttpEndpoints() ... .WithReference(appConfig); Connection Passes connection string to web application resource
Feature flags need ID based merging Standard .NET configuration based on array position, not name builder.Services.Configure<ConfigurationFeatureDefinitionProviderOptions>( options => { options.CustomConfigurationMergingEnabled = true; } ); Refresh requires middleware var app = builder.Build(); app.UseAzureAppConfiguration();
OpenTelemetry Use signals to send feature specific observability data Azure Log Analytics and other commercial products Aspire Dashboard for development
more autonomy Full control over deployment and release Deployment should include creation of flags in external environment Flags introduce technical debt Have to clean up afterwards Plan for removing flags in a later sprint
Different environments Feature: For a period of time Increasing percentage Cohorts Different groups, size, audience Canary Early adopters General public Can offer opt-in model
App Configuration Script Use Azure CLI for App Configuration Azure.Data.AppConfiguration var client = new ConfigurationClient( new Uri("https://<your-store>.azconfig.io"), new DefaultAzureCredential()); # Enable feature flag az appconfig feature enable \ --name $(APP_CONFIG_NAME) --feature "Chatbot" var flag = new FeatureFlagConfigurationSetting(featureId: "Chatbot", isEnabled: true); await client.SetConfigurationSettingAsync(flag); # Enable with percentage rollout az appconfig feature filter update \ --name $(APP_CONFIG_NAME) --feature "Chatbot" \ --filter-name "Microsoft.Percentage" \ --filter-parameters Value=$NewPercentage
led by hypothesis Increase percentage that has feature enabled Measure results, outcome and gather feedback Previously: Now : Routing to two different implementations Percentage filter in single implementation
is not same as a feature under a toggle Separate flag management from app In case app becomes unresponsive for managing flags Monitor usage of flags New, not used yet Not used (remove from config) Being used Everyone uses one variation (remove from code) Enable just one toggle at a time Measure outcome and give time to stabilize