Skip to content

Commit 1833c8b

Browse files
authored
Merge pull request #290444 from rossgrambo/rossgrambo/variant-feature-flags-doc-rewrite
Adds variant feature flags docs
2 parents 5a3d423 + 6ca037e commit 1833c8b

File tree

10 files changed

+363
-3
lines changed

10 files changed

+363
-3
lines changed

articles/azure-app-configuration/TOC.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,12 @@
158158
href: howto-targetingfilter.md
159159
- name: ASP.NET Core
160160
href: howto-targetingfilter-aspnet-core.md
161+
- name: Use variant feature flags
162+
items:
163+
- name: Overview
164+
href: use-variant-feature-flags.md
165+
- name: ASP.NET Core
166+
href: use-variant-feature-flags-aspnet-core.md
161167
- name: Enable Azure monitoring
162168
items:
163169
- name: Monitor App Configuration

articles/azure-app-configuration/index.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,8 @@ landingContent:
162162
url: howto-timewindow-filter.md
163163
- text: Roll out features to targeted audience
164164
url: howto-targetingfilter.md
165+
- text: Use variant feature flags
166+
url: use-variant-feature-flags.md
165167
- linkListType: reference
166168
links:
167169
- text: .NET feature management

articles/azure-app-configuration/manage-feature-flags.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ ms.custom: "devx-track-csharp, mvc"
1515

1616
# Quickstart: Manage feature flags in Azure App Configuration
1717

18-
Azure App Configuration includes feature flags, which you can use to enable or disable a functionality, and variant feature flags (preview), which allow multiple variations of a feature flag.
18+
Azure App Configuration includes feature flags, which you can use to enable or disable a functionality, and variant feature flags, which allow multiple variations of a feature flag.
1919

2020
The Feature manager in the Azure portal provides a UI for creating and managing the feature flags and the variant feature flags that you use in your applications.
2121

@@ -59,9 +59,9 @@ az appconfig feature set --name <name> --feature Beta
5959

6060
---
6161

62-
## Create a variant feature flag (preview)
62+
## Create a variant feature flag
6363

64-
Add a new variant feature flag (preview) by opening your Azure App Configuration store in the Azure portal and from the **Operations** menu, select **Feature manager** > **Create**. Then select **Variant feature flag (Preview)**.
64+
Add a new variant feature flag by opening your Azure App Configuration store in the Azure portal and from the **Operations** menu, select **Feature manager** > **Create**. Then select **Variant feature flag**.
6565

6666
:::image type="content" source="media\manage-feature-flags\variant-feature-flags-menu.png" alt-text="Screenshot of the Azure platform. Create a variant feature flag.":::
6767

19.7 KB
Loading
37.3 KB
Loading
30.2 KB
Loading
37.2 KB
Loading
25.5 KB
Loading
Lines changed: 276 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,276 @@
1+
---
2+
title: 'Tutorial: Use variant feature flags from Azure App Configuration in an ASP.NET application'
3+
titleSuffix: Azure App configuration
4+
description: In this tutorial, you learn how to use variant feature flags in an ASP.NET application
5+
#customerintent: As a user of Azure App Configuration, I want to learn how I can use variants and variant feature flags in my ASP.NET application.
6+
author: rossgrambo
7+
ms.author: rossgrambo
8+
ms.service: azure-app-configuration
9+
ms.devlang: csharp
10+
ms.topic: tutorial
11+
ms.date: 10/18/2024
12+
---
13+
14+
# Tutorial: Use variant feature flags from Azure App Configuration in an ASP.NET application
15+
16+
In this tutorial, you use a variant feature flag to manage experiences for different user segments in an example application, *Quote of the Day*. You utilize the variant feature flag created in [Use variant feature flags](./use-variant-feature-flags.md). Before proceeding, ensure you create the variant feature flag named *Greeting* in your App Configuration store.
17+
18+
## Prerequisites
19+
20+
* Ensure the [.NET CLI](/dotnet/core/tools) is installed on your machine.
21+
* Follow the [Use variant feature flags](./use-variant-feature-flags.md) tutorial and create the variant feature flag named *Greeting*.
22+
23+
## Create an ASP.NET Core web app
24+
25+
1. Run the following code in a command prompt. This command creates a new Razor Pages application in ASP.NET Core, using Individual account auth, and places it in an output folder named *QuoteOfTheDay*.
26+
27+
```dotnetcli
28+
dotnet new razor --auth Individual -o QuoteOfTheDay
29+
```
30+
31+
1. Create a [user secret](/aspnet/core/security/app-secrets) for the application by navigating into the *QuoteOfTheDay* folder and run the following command. This secret holds the endpoint for your App Configuration.
32+
33+
```dotnetcli
34+
dotnet user-secrets set Endpoints:AppConfiguration "<App Configuration Endpoint>"
35+
```
36+
37+
1. Add the latest versions of the required packages.
38+
39+
```dotnetcli
40+
dotnet add package Azure.Identity
41+
dotnet add package Microsoft.Extensions.Configuration.AzureAppConfiguration
42+
dotnet add package Microsoft.FeatureManagement.AspNetCore
43+
```
44+
45+
## Connect to App Configuration for feature management
46+
47+
1. In *Program.cs*, add the following using statements.
48+
49+
```csharp
50+
using Azure.Identity;
51+
using Microsoft.Extensions.Configuration.AzureAppConfiguration;
52+
using Microsoft.FeatureManagement;
53+
```
54+
55+
1. In *Program.cs*, under the line `var builder = WebApplication.CreateBuilder(args);`, add the App Configuration provider, which pulls down the configuration from Azure App Configuration when the application starts. By default, the `UseFeatureFlags` method pulls down all feature flags with no label.
56+
57+
You use the `DefaultAzureCredential` to authenticate to your App Configuration store. Follow the [instructions](./concept-enable-rbac.md#authentication-with-token-credentials) to assign your credential the **App Configuration Data Reader** role. Be sure to allow sufficient time for the permission to propagate before running your application.
58+
59+
```csharp
60+
builder.Configuration
61+
.AddAzureAppConfiguration(options =>
62+
{
63+
string endpoint = builder.Configuration.Get("Endpoints:AppConfiguration");
64+
options.Connect(new Uri(endpoint), new DefaultAzureCredential());
65+
66+
options.UseFeatureFlags();
67+
});
68+
```
69+
70+
1. Add Azure App Configuration and feature management services and enable targeting for feature management.
71+
72+
```csharp
73+
// Add Azure App Configuration and feature management services to the container.
74+
builder.Services.AddAzureAppConfiguration()
75+
.AddFeatureManagement()
76+
.WithTargeting();
77+
```
78+
79+
1. Under the line `var app = builder.Build();`, add Azure App Configuration middleware for dynamic configuration refresh.
80+
81+
```csharp
82+
// Use Azure App Configuration middleware for dynamic configuration refresh.
83+
app.UseAzureAppConfiguration();
84+
```
85+
86+
## Use the variant feature flag
87+
88+
1. Open *QuoteOfTheDay* > *Pages* > *Index.cshtml.cs* and replace the content with the following code.
89+
90+
```csharp
91+
using Microsoft.AspNetCore.Mvc;
92+
using Microsoft.AspNetCore.Mvc.RazorPages;
93+
using Microsoft.FeatureManagement;
94+
95+
namespace QuoteOfTheDay.Pages;
96+
97+
public class Quote
98+
{
99+
public string Message { get; set; }
100+
101+
public string Author { get; set; }
102+
}
103+
104+
public class IndexModel(IVariantFeatureManagerSnapshot featureManager) : PageModel
105+
{
106+
private readonly IVariantFeatureManagerSnapshot _featureManager = featureManager;
107+
108+
private Quote[] _quotes = [
109+
new Quote()
110+
{
111+
Message = "You cannot change what you are, only what you do.",
112+
Author = "Philip Pullman"
113+
}];
114+
115+
public Quote? Quote { get; set; }
116+
117+
public string GreetingMessage { get; set; }
118+
119+
public async void OnGet()
120+
{
121+
Quote = _quotes[new Random().Next(_quotes.Length)];
122+
123+
Variant variant = await _featureManager.GetVariantAsync("Greeting", HttpContext.RequestAborted);
124+
125+
if (variant != null)
126+
{
127+
GreetingMessage = variant.Configuration?.Get<string>() ?? "";
128+
}
129+
else
130+
{
131+
_logger.LogWarning("No variant given. Either the feature flag named 'Greeting' is not defined or the variants are not defined properly.");
132+
}
133+
}
134+
}
135+
```
136+
137+
You call `GetVariantAsync` to retrieve the variant of the *Greeting* feature flag for the current user and assign its value to the `GreetingMessage` property of the page model.
138+
139+
1. In *QuoteOfTheDay* > *Pages* > *Shared* > *_Layout.cshtml*, under where `QuoteOfTheDay.styles.css` is added, add the following reference to the font-awesome CSS library.
140+
141+
```css
142+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
143+
```
144+
145+
1. Open *index.cshtml* and replace its content with the following code.
146+
147+
```cshtml
148+
@page
149+
@model IndexModel
150+
@{
151+
ViewData["Title"] = "Home page";
152+
ViewData["Username"] = User.Identity?.Name ?? string.Empty;
153+
}
154+
155+
<style>
156+
body {
157+
font-family: Arial, sans-serif;
158+
background-color: #f4f4f4;
159+
color: #333;
160+
}
161+
162+
.quote-container {
163+
background-color: #fff;
164+
margin: 2em auto;
165+
padding: 2em;
166+
border-radius: 8px;
167+
max-width: 750px;
168+
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2);
169+
display: flex;
170+
justify-content: space-between;
171+
align-items: start;
172+
position: relative;
173+
}
174+
175+
.vote-container {
176+
position: absolute;
177+
top: 10px;
178+
right: 10px;
179+
display: flex;
180+
gap: 0em;
181+
}
182+
183+
.vote-container .btn {
184+
background-color: #ffffff; /* White background */
185+
border-color: #ffffff; /* Light blue border */
186+
color: #333
187+
}
188+
189+
.vote-container .btn:focus {
190+
outline: none;
191+
box-shadow: none;
192+
}
193+
194+
.vote-container .btn:hover {
195+
background-color: #F0F0F0; /* Light gray background */
196+
}
197+
198+
.greeting-content {
199+
font-family: 'Georgia', serif; /* More artistic font */
200+
}
201+
202+
.quote-content p.quote {
203+
font-size: 2em; /* Bigger font size */
204+
font-family: 'Georgia', serif; /* More artistic font */
205+
font-style: italic; /* Italic font */
206+
color: #4EC2F7; /* Medium-light blue color */
207+
}
208+
</style>
209+
210+
<div class="quote-container">
211+
<div class="quote-content">
212+
<h3 class="greeting-content">@(Model.GreetingMessage)</h3>
213+
<br />
214+
<p class="quote">“@(Model.Quote?.Message ?? "< Quote not found >")”</p>
215+
<p>- <b>@(Model.Quote?.Author ?? "Unknown")</b></p>
216+
</div>
217+
218+
<div class="vote-container">
219+
<button class="btn btn-primary" onclick="heartClicked(this)">
220+
<i class="far fa-heart"></i> <!-- Heart icon -->
221+
</button>
222+
</div>
223+
</div>
224+
225+
<script>
226+
function heartClicked(button) {
227+
var icon = button.querySelector('i');
228+
icon.classList.toggle('far');
229+
icon.classList.toggle('fas');
230+
}
231+
</script>
232+
```
233+
234+
This code displays the UI of the *Quote of the Day* application and shows the `GreetingMessage` from the page model. The JavaScript handler `heartClicked` is triggered when the heart button is clicked.
235+
236+
### Build and run the app
237+
238+
1. Build and run the application.
239+
240+
```dotnetcli
241+
dotnet build
242+
dotnet run
243+
```
244+
1. Once the application is loaded, select **Register** at the top right to register a new user.
245+
246+
:::image type="content" source="media/use-variant-feature-flags-aspnet-core/register.png" alt-text="Screenshot of the Quote of the day app, showing Register.":::
247+
248+
1. Register a new user named *[email protected]*.
249+
250+
1. Select the link **Click here to validate email** after entering user information.
251+
252+
:::image type="content" source="media/use-variant-feature-flags-aspnet-core/click-to-confirm.png" alt-text="Screenshot of the Quote of the day app, showing click to confirm.":::
253+
254+
1. Repeat the same steps to register a second user named *[email protected]*.
255+
256+
> [!NOTE]
257+
> It's important for the purpose of this tutorial to use these names exactly. As long as the feature has been configured as expected, the two users should see different variants.
258+
259+
1. Select **Login** at the top right to sign in as [email protected].
260+
261+
:::image type="content" source="media/use-variant-feature-flags-aspnet-core/login.png" alt-text="Screenshot of the Quote of the day app, showing **Login**.":::
262+
263+
1. Once logged in, you see a long greeting message for **[email protected]**
264+
265+
:::image type="content" source="media/use-variant-feature-flags-aspnet-core/long-variant.png" alt-text="Screenshot of the Quote of the day app, showing a long message for the user.":::
266+
267+
1. Click *Logout* and login as **[email protected]**, you see the simple greeting message.
268+
269+
:::image type="content" source="media/use-variant-feature-flags-aspnet-core/simple-variant.png" alt-text="Screenshot of the Quote of the day app, showing a simple message for the user.":::
270+
271+
## Next steps
272+
273+
For the full feature rundown of the .NET feature management library, refer to the following document.
274+
275+
> [!div class="nextstepaction"]
276+
> [.NET Feature Management](./feature-management-dotnet-reference.md)
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
---
2+
title: 'Use variant feature flags'
3+
titleSuffix: Azure App configuration
4+
description: In this tutorial, you learn how to set up and use variant feature flags in an App Configuration
5+
#customerintent: As a user of Azure App Configuration, I want to learn how I can use variants and variant feature flags in my application.
6+
author: rossgrambo
7+
ms.author: rossgrambo
8+
ms.service: azure-app-configuration
9+
ms.devlang: csharp
10+
ms.topic: tutorial
11+
ms.date: 10/18/2024
12+
---
13+
14+
# Use variant feature flags
15+
16+
Variant feature flags enable your application to support multiple variants of a feature. The variants of your feature can be assigned to specific users, groups, or percentile buckets. These flags can be useful for feature rollouts, configuration rollouts, and feature experimentation (also known as A/B testing).
17+
18+
## What is a variant feature flag?
19+
20+
A variant feature flag is an enhanced feature flag that supports multiple states or variations. While it can still be toggled on or off, it also allows for different variants with configurations. A variant is defined with a *Name* and an optional *Configuration Value*. The name is an identifier to tell variants apart. The configuration value can range from simple JSON primitives to complex JSON objects. You can use variants to differentiate functionalities or user experiences and optionally configure these functionalities or user experiences with variant configuration values. Additionally, a variant feature flag includes allocation rules, which define the target audience for each variant.
21+
22+
### Variants
23+
24+
The following example shows two variants using JSON objects for the configuration value.
25+
26+
| Variant Name | Variant Configuration Value |
27+
|---|---|
28+
| Minimal | { "maxitems": 10, "showAds": false } |
29+
| Standard | { "maxitems": 30, "showAds": true } |
30+
31+
### Allocation
32+
33+
Allocation controls which segment of users get each variant. The following example allocates 10% of users to get the *Minimal* variant and 90% to get the *Standard* variant.
34+
35+
| Variant | Allocation | Remarks |
36+
|---|---|---|
37+
| Minimal | 10% | Assign the variant to users in the 0th to 10th percentile. |
38+
| Standard | 90% | Assign the variant to users in the 10th to 100th percentile. |
39+
40+
### Overrides
41+
42+
You can assign variants to specific groups or users irrespective of the percentage allocation. The following example assigns users in the *Beta Tester* group the *Minimal* variant.
43+
44+
| Group Name | Variant |
45+
|---|---|
46+
| Beta Tester | Minimal |
47+
48+
### Default variants and kill switch
49+
50+
Variant feature flags have two variant defaults, **DefaultWhenEnabled** and **DefaultWhenDisabled**.
51+
- The **DefaultWhenEnabled** variant takes effect if the flag is enabled but the allocation doesn't assign all percentiles. Any user placed in an unassigned percentile receives the **DefaultWhenEnabled** variant.
52+
- The **DefaultWhenDisabled** variant takes effect if the flag is disabled, done by setting the **Enabled** field to false, also known as using the "kill switch".
53+
54+
The **kill switch** is used to stop users from allocating. Used when one or more of the variants have a problem- whether it's a bug, regression, or bad performance. To use the kill switch, set the **Enabled** field of the variant flag to false. All users now are given the **DefaultWhenDisabled** variant, regardless of which percentiles or overridden users/groups they were a part of.
55+
56+
## Build an app with a variant feature flag
57+
58+
In this tutorial, you create a web app named _Quote of the Day_. When the app is loaded, it displays a quote. Users can interact with the heart button to like it. To improve user engagement, you want to explore whether a personalized greeting message increases the number of users who like the quote. Users who receive the _None_ variant see no greeting. Users who receive the _Simple_ variant get a simple greeting message. Users who receive the _Long_ variant get a slightly longer greeting.
59+
60+
## Prerequisites
61+
62+
* An Azure subscription. If you don’t have one, [create one for free](https://azure.microsoft.com/free/).
63+
* An [App Configuration store](./quickstart-azure-app-configuration-create.md).
64+
65+
## Create a variant feature flag
66+
67+
1. Create a variant feature flag called *Greeting* with no label in your App Configuration store. It includes three variants: *None*, *Simple*, and *Long*, each corresponding to different greeting messages. Refer to the following table for their configuration values and allocation settings. For more information on how to add a variant feature flag, see [Create a variant feature flag](./manage-feature-flags.md#create-a-variant-feature-flag).
68+
69+
| Variant Name | Variant Configuration Value | Allocation|
70+
|---|---|---|
71+
| None *(Default)* | null | 50% |
72+
| Simple | "Hello!" | 25% |
73+
| Long | "I hope this makes your day!" | 25% |
74+
75+
2. Continue to the following instructions to use the variant feature flag in your application for the language or platform you're using.
76+
* [ASP.NET Core](./use-variant-feature-flags-aspnet-core.md)

0 commit comments

Comments
 (0)