

# Creating a feature flag configuration profile in AWS AppConfig
Creating a feature flag configuration profile

You can use feature flags to enable or disable features within your applications or to configure different characteristics of your application features using flag attributes. AWS AppConfig stores feature flag configurations in the AWS AppConfig hosted configuration store in a feature flag format that contains data and metadata about your flags and the flag attributes.

**Note**  
When you create a feature flag configuration profile, you can create a basic feature flag as part of the configuration profile workflow. AWS AppConfig also supports multi-variant feature flags. *Multi-variant feature flags* enable you to define a set of possible flag values to return for a request. When requesting a flag configured with variants, your application provides context that AWS AppConfig evaluates against a set of user-defined rules. Depending on the context specified in the request and the rules defined for the variant, AWS AppConfig returns different flag values to the application.  
To create multi-variant feature flags, create a configuration profile first, and then edit any flags within the configuration profile to add variants. For more information, see [Creating multi-variant feature flags](appconfig-creating-multi-variant-feature-flags.md).

**Topics**
+ [

## Understanding feature flag attributes
](#appconfig-creating-configuration-profile-feature-flag-attributes)
+ [

# Creating a feature flag configuration profile (console)
](appconfig-creating-feature-flag-configuration-create-console.md)
+ [

# Creating a feature flag configuration profile (command line)
](appconfig-creating-feature-flag-configuration-commandline.md)
+ [

# Creating multi-variant feature flags
](appconfig-creating-multi-variant-feature-flags.md)
+ [

# Understanding the type reference for AWS.AppConfig.FeatureFlags
](appconfig-type-reference-feature-flags.md)
+ [

# Saving a previous feature flag version to a new version
](appconfig-creating-configuration-profile-feature-flags-editing-version.md)

## Understanding feature flag attributes


When you create a feature flag configuration profile—or create a new flag within an existing configuration profile—you can specify attributes and corresponding constraints for the flag. An attribute is a field that you associate with your feature flag to express properties related to your feature flag. Attributes are delivered to your application with your flag key and the `enable` or `disable` value of the flag.

Constraints ensure that any unexpected attribute values are not deployed to your application. The following image shows an example.

![\[Example of flag attributes for an AWS AppConfig feature flag\]](http://docs.aws.amazon.com/appconfig/latest/userguide/images/appconfig-flag-attributes.png)


**Note**  
Note the following information about flag attributes.  
For attribute names, the word "enabled" is reserved. You can't create a feature flag attribute called "enabled". There are no other reserved words.
The attributes of a feature flag are only included in the `GetLatestConfiguration` response if that flag is enabled. 
Flag attribute keys for a given flag must be unique. 

AWS AppConfig supports the following types of flag attributes and their corresponding constraints.

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/appconfig/latest/userguide/appconfig-creating-configuration-and-profile-feature-flags.html)

# Creating a feature flag configuration profile (console)


Use the following procedure to create an AWS AppConfig feature flag configuration profile by using the AWS AppConfig console. At the time you create the configuration profile, you can also create a basic feature flag. 

**To create a configuration profile**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/appconfig/](https://console.aws.amazon.com/systems-manager/appconfig/).

1. In the navigation pane, choose **Applications**, and then choose an application you created in [Creating a namespace for your application in AWS AppConfig](appconfig-creating-namespace.md).

1. On the **Configuration profiles and feature flags** tab, choose **Create configuration**.

1. In the **Configuration options** section, choose **Feature flag**.

1. In the **Configuration profile** section, for **Configuration profile name**, enter a name.

1. (Optional) Expand **Description** and enter a description.

1. (Optional) Expand **Additional options** and complete the following, as necessary.

   1. In the **Encryption** list, choose an AWS Key Management Service (AWS KMS) key from the list. This customer managed key enables you to encrypt new configuration data versions in the AWS AppConfig hosted configuration store. For more information about this key, see **AWS AppConfig supports customer manager keys** in [Security in AWS AppConfig](appconfig-security.md).

   1. In the **Tags** section, choose **Add new tag**, and then specify a key and optional value. 

1. Choose **Next**.

1. In the **Feature flag definition** section, for **Flag name**, enter a name.

1. For **Flag key** enter a flag identifier to distinguish flags within the same configuration profile. Flags within the same configuration profile can't have the same key. After the flag is created, you can edit the flag name, but not the flag key. 

1. (Optional) Expand **Description** and enter information about this flag.

1. Select **This is a short-term flag** and optionally choose a date for when the flag should be disabled or deleted. AWS AppConfig does *not* disable the flag on the deprecation date. 

1. (Optional) In the **Feature flag attributes** section, choose **Define attribute**. Attributes enable you to provide additional values within your flag. For more information about attributes and constraints, see [Understanding feature flag attributes](appconfig-creating-configuration-and-profile-feature-flags.md#appconfig-creating-configuration-profile-feature-flag-attributes).

   1. For **Key**, specify a flag key and choose its type from the **Type** list. For information about the supported options for the **Value** and **Constraints** fields, see the previously referenced section about attributes.

   1. Select **Required value** to specify whether an attribute value is required.

   1. Choose **Define attribute** to add additional attributes.

1. In the **Feature flag value** section, choose **Enabled** to enable the flag. Use this same toggle to disable a flag when it reaches a specified deprecation date, if applicable.

1. Choose **Next**.

1. On the **Review and save** page, verify the details of the flag and then **Save and continue to deploy**.

Proceed to [Deploying feature flags and configuration data in AWS AppConfig](deploying-feature-flags.md).

# Creating a feature flag configuration profile (command line)


The following procedure describes how to use the AWS Command Line Interface (on Linux or Windows) or Tools for Windows PowerShell to create an AWS AppConfig feature flag configuration profile. At the time you create the configuration profile, you can also create a basic feature flag.

**To create a feature flag configuration**

1. Open the AWS CLI.

1. Create a feature flag configuration profile specifying its **Type** as `AWS.AppConfig.FeatureFlags`. The configuration profile must use `hosted` for the location URI.

------
#### [ Linux ]

   ```
   aws appconfig create-configuration-profile \
     --application-id APPLICATION_ID \
     --name CONFIGURATION_PROFILE_NAME \
     --location-uri hosted \
     --type AWS.AppConfig.FeatureFlags
   ```

------
#### [ Windows ]

   ```
   aws appconfig create-configuration-profile ^
     --application-id APPLICATION_ID ^
     --name CONFIGURATION_PROFILE_NAME ^
     --location-uri hosted ^
     --type AWS.AppConfig.FeatureFlags
   ```

------
#### [ PowerShell ]

   ```
   New-APPCConfigurationProfile `
     -Name CONFIGURATION_PROFILE_NAME `
     -ApplicationId APPLICATION_ID `
     -LocationUri hosted `
     -Type AWS.AppConfig.FeatureFlags
   ```

------

1. Create your feature flag configuration data. Your data must be in a JSON format and conform to the `AWS.AppConfig.FeatureFlags` JSON schema. For more information about the schema, see [Understanding the type reference for AWS.AppConfig.FeatureFlags](appconfig-type-reference-feature-flags.md).

1. Use the `CreateHostedConfigurationVersion` API to save your feature flag configuration data to AWS AppConfig.

------
#### [ Linux ]

   ```
   aws appconfig create-hosted-configuration-version \
     --application-id APPLICATION_ID \
     --configuration-profile-id CONFIGURATION_PROFILE_ID \
     --content-type "application/json" \
     --content file://path/to/feature_flag_configuration_data.json \
     --cli-binary-format raw-in-base64-out
   ```

------
#### [ Windows ]

   ```
   aws appconfig create-hosted-configuration-version ^
     --application-id APPLICATION_ID ^
     --configuration-profile-id CONFIGURATION_PROFILE_ID ^
     --content-type "application/json" ^
     --content file://path/to/feature_flag_configuration_data.json ^
     --cli-binary-format raw-in-base64-out
   ```

------
#### [ PowerShell ]

   ```
   New-APPCHostedConfigurationVersion `
     -ApplicationId APPLICATION_ID `
     -ConfigurationProfileId CONFIGURATION_PROFILE_ID `
     -ContentType "application/json" `
     -Content file://path/to/feature_flag_configuration_data.json
   ```

------

   The command loads the content specified for the `Content` parameter from disk. The content must be similar to the following example.

   ```
   {
       "flags": {
           "ui_refresh": {
               "name": "UI Refresh"
           }
       },
       "values": {
           "ui_refresh": {
               "enabled": false,
               "attributeValues": {
                   "dark_mode_support": true
               }
           }
       },
       "version": "1"
   }
   ```

   The system returns information like the following.

------
#### [ Linux ]

   ```
   {
      "ApplicationId"          : "ui_refresh",
      "ConfigurationProfileId" : "UI Refresh",
      "VersionNumber"          : "1",
      "ContentType"            : "application/json"
   }
   ```

------
#### [ Windows ]

   ```
   {
      "ApplicationId"          : "ui_refresh",
      "ConfigurationProfileId" : "UI Refresh",
      "VersionNumber"          : "1",
      "ContentType"            : "application/json"
   }
   ```

------
#### [ PowerShell ]

   ```
   ApplicationId          : ui_refresh
   ConfigurationProfileId : UI Refresh
   VersionNumber          : 1
   ContentType            : application/json
   ```

------

   The `service_returned_content_file` contains your configuration data that includes some AWS AppConfig generated metadata.
**Note**  
When you create the hosted configuration version, AWS AppConfig verifies that your data conforms to the `AWS.AppConfig.FeatureFlags` JSON schema. AWS AppConfig additionally validates that each feature flag attribute in your data satisfies the constraints you defined for those attributes.

# Creating multi-variant feature flags


Feature flag variants enable you to define a set of possible flag values to return for a request. You can also configure different statuses (enabled or disabled) for multi-variant flags. When requesting a flag configured with variants, your application provides context that AWS AppConfig evaluates against a set of user-defined rules. Depending on the context specified in the request and the rules defined for the variant, AWS AppConfig returns different flag values to the application.

The following screenshot shows an example of a feature flag with three user-defined variants and the default variant.

![\[An example screenshot of a feature flag with variants.\]](http://docs.aws.amazon.com/appconfig/latest/userguide/images/flag-variant-example.png)


**Topics**
+ [

# Understanding multi-variant feature flag concepts and common use cases
](appconfig-creating-multi-variant-feature-flags-concepts.md)
+ [

# Understanding multi-variant feature flag rules
](appconfig-creating-multi-variant-feature-flags-rules.md)
+ [

# Creating a multi-variant feature flag
](appconfig-creating-multi-variant-feature-flags-procedures.md)

# Understanding multi-variant feature flag concepts and common use cases


To help you better understand feature flag variants, this section explains flag variant concepts and common use cases.

**Concepts**
+ **Feature flag**: An AWS AppConfig configuration type used to control the behavior of a feature in an application. A flag has a status (enabled or disabled) and an optional set of attributes containing arbitrary string, numeric, boolean, or array values.
+ **Feature flag variant**: A specific combination of status and attribute values belonging to a feature flag. A feature flag may have multiple variants.
+ **Variant rule**: A user-defined expression used to select a feature flag variant. Each variant has its own rule that AWS AppConfig evaluates to determine whether to return it or not.
+ **Default variant**: A special variant that is returned when no other variant is selected. All multi-variant feature flags have a default variant.

  Note, the default variant must be last in your ordering of variants, and it can't have rules associated with it. If it's not defined last, AWS AppConfig returns a `BadRequestException` when you try to create the multi-variant flag.
+ **Context**: User-defined keys and values passed to AWS AppConfig at configuration retrieval time. Context values are used during rule evaluation to select the feature flag variant to return.

**Note**  
AWS AppConfig agent evaluates variant rules and determines which rule applies to the request based on the provided context. For more information about retrieving multi-varient feature flags, see [Retrieving basic and multi-variant feature flags](appconfig-integration-retrieving-feature-flags.md).

**Common use cases**

This section describes two common use cases for feature flag variants.

*User segmentation*

User segmentation is the process of dividing users based on certain attributes. As an example, you could use flag variants to expose a feature to some users but not others based on their user ID, geographic location, device type, or purchase frequency.

Using the example of purchase frequency, suppose your commerce application supports a feature to increase customer loyalty. You can use flag variants to configure different incentive types to be shown to a user based on when they last purchased something. A new user might be offered a small discount to encourage them to become a customer, whereas a repeat customer might be given a larger discount if they purchase something from a new category.

*Traffic splitting*

Traffic splitting is the process of selecting a random, but consistent, flag variant based on a context value you define. For example, you may want to perform an experiment where a small percentage of your users (identified by their user ID) sees a particular variant. Or, you may want to execute a gradual feature rollout where a feature is first exposed to 5% of your users, then 15%, then 40%, then 100%, while maintaining a consistent user experience throughout the rollout.

Using the experimentation example, you could use flag variants to test a new button style for the primary action on your application homepage to see if it drives more clicks. For your experiment, you could create a flag variant with a traffic splitting rule that selects 5% of users to see the new style, while the default variant indicates the users that should continue to see the existing style. If the experiment is successful, you can increase the percentage value, or even turn that variant into the default.

# Understanding multi-variant feature flag rules


When you create a feature flag variant, you specify a rule for it. Rules are expressions that take context values as input and produce a boolean result as output. For example, you could define a rule to select a flag variant for beta users, identified by their account ID, testing a user interface refresh. For this scenario, you do the following:

1. Create a new feature flag configuration profile called *UI Refresh*.

1. Create a new feature flag called *ui\$1refresh*.

1. Edit the feature flag after you create it to add variants.

1. Create and enable a new variant called *BetaUsers*.

1. Define a rule for *BetaUsers* that selects the variant if the account ID from the request context is in a list of account IDs approved to view the new beta experience.

1. Confirm that the default variant’s status is set to **Disabled**.

**Note**  
Variants are evaluated as an ordered list based on the order they are defined in the console. The variant at the top of the list is evaluated first. If no rules match the supplied context, AWS AppConfig returns the Default variant.

When AWS AppConfig processes the feature flag request, it compares the supplied context, which includes the AccountID (for this example) to the BetaUsers variant first. If the context matches the rule for BetaUsers, AWS AppConfig returns the configuration data for the beta experience. If the context doesn’t include an account ID or if the account ID ends in anything other than 123, AWS AppConfig returns configuration data for the Default rule, which means the user views the current experience in production.

**Note**  
For information about retrieving multi-variant feature flags, see [Retrieving basic and multi-variant feature flags](appconfig-integration-retrieving-feature-flags.md).

# Defining rules for multi-variant feature flags


A variant rule is an expression comprised of one or more operands and an operator. An operand is a specific value used during the evaluation of a rule. Operand values can be either static, such as a literal number or string, or variable, such as the value found in a context or the result of another expression. An operator, such as "greater than", is a test or action applied to its operands that produces a value. A variant rule expression must produce either a "true" or "false" to be valid.

**Operands**


****  

| Type | Description | Example | 
| --- | --- | --- | 
|  String  |  A sequence of UTF-8 characters, enclosed in double-quotes.  |  <pre>"apple", "Ḽơᶉëᶆ ȋṕšᶙṁ"</pre>  | 
|  Integer  |  A 64-bit integer value.  |  <pre>-7, 42 </pre>  | 
|  Float  |  A 64-bit IEEE-754 floating-point value.  |  <pre>3.14, 1.234e-5</pre>  | 
|  Timestamp  |  A specific moment in time as described by the [W3C note on date and time formats](https://www.w3.org/TR/NOTE-datetime).  |  <pre>2012-03-04T05:06:07-08:00, 2024-01</pre>  | 
|  Boolean  |  A true or false value.  |  <pre>true, false</pre>  | 
|  Context value  |  A parameterized value in the form of \$1*key* that is retrieved from the context during rule evaluation.  |  <pre>$country, $userId</pre>  | 

**Comparison operators**


****  

| Operator | Description | Example | 
| --- | --- | --- | 
|  eq  |  Determines whether a context value is equal to a given value.  |  <pre>(eq $state "Virginia")</pre>  | 
|  gt  |  Determines whether a context value is greater than a given value.  |  <pre>(gt $age 65)</pre>  | 
|  gte  |  Determines whether a context value is greater than or equal to a given value.  |  <pre>(gte $age 65)</pre>  | 
|  lt  |  Determines whether a context value is less than a given value.  |  <pre>(lt $age 65)</pre>  | 
|  lte  |  Determines whether a context value is less than or equal to a given value.  |  <pre>(lte $age 65)</pre>  | 

**Logical operators**


****  

| Operator | Description | Example | 
| --- | --- | --- | 
|  and  |  Determines if both operands are true.  |  <pre>(and <br />    (eq $state "Virginia") <br />    (gt $age 65)<br />)</pre>  | 
|  or  |  Determines if at least one of the operands is true.  |  <pre>(or<br />    (eq $state "Virginia") <br />    (gt $age 65)<br />)</pre>  | 
|  not  |  Reverses the value of an expression.  |  <pre>(not (eq $state "Virginia"))</pre>  | 

**Custom operators**


****  

| Operator | Description | Example | 
| --- | --- | --- | 
|  begins\$1with  |  Determines whether a context value begins with a given prefix.  |  <pre>(begins_with $state "A")</pre>  | 
|  ends\$1with  |  Determines whether a context value ends with a given prefix.  |  <pre>(ends_with $email "amazon.com")</pre>  | 
|  contains  |  Determines whether a context value contains a given substring.  |  <pre>(contains $promoCode "WIN")</pre>  | 
|  in  |  Determines whether a context value is contained within a list of constants.  |  <pre>(in $userId ["123", "456"])</pre>  | 
|  matches  |  Determines whether a context value matches a given regex pattern.  |  <pre>(matches in::$greeting pattern::"h.*y")</pre>  | 
|  exists  |  Determines whether any value was provided for a context key.  |  <pre>(exists key::"country")</pre>  | 
|  split  |  Evaluates to `true` for a given percentage of traffic based on a consistent hash of the provided context value(s). For a detailed explanation of how `split` works, see the next section in this topic, [Understanding the split operator](appconfig-creating-multi-variant-feature-flags-rules.md#appconfig-creating-multi-variant-feature-flags-rules-operators-split). Note that `seed` is an optional property. If you don't specify `seed`, the hash is *locally* consistent, meaning traffic will be split consistently for that flag, but other flags receiving the same context value may split traffic differently. If `seed` is provided, each unique value is guaranteed to split traffic consistently across feature flags, configuration profiles, and AWS accounts.  |  <pre>(split pct::10 by::$userId seed::"abc")</pre>  | 

## Understanding the split operator


The following section describes how the `split` operator behaves when used in different scenarios. As a reminder, `split` evaluates to `true` for a given percentage of traffic based on a consistent hash of the provided context value. To understand this better, consider the following baseline scenario that uses split with two variants:

```
A: (split by::$uniqueId pct::20)
C: <no rule>
```

As expected, providing a random set of `uniqueId` values produces a distribution that's approximately:

```
A: 20%
C: 80%
```

If you add a third variant, but use the same split percentage like so:

```
A: (split by::$uniqueId pct::20)
B: (split by::$uniqueId pct::20)
C: <default>
```

You end up with the following distribution:

```
A: 20%
B: 0%
C: 80%
```

This potentially unexpected distribution happens because each variant rule is evaluated in order and the first match determines the returned variant. When rule A is evaluated, 20% of `uniqueId` values match it, so the first variant is returned. Next, rule B is evaluated. However, all of the `uniqueId` values that would have matched the second split statement were already matched by variant rule A, so no values match B. The default variant is returned instead.

Now consider a third example.

```
A: (split by::$uniqueId pct::20)
B: (split by::$uniqueId pct::25)
C: <default>
```

As with the previous example, the first 20% of `uniqueId` values match rule A. For variant rule B, 25% of all `uniqueId` values would match, but most of those previously matched rule A. That leaves 5% of the total for variant B, with the remainder receiving variant C. The distribution would look like the following:

```
A: 20%
B: 5%
C: 75%
```

**Using the `seed` property**  
You can use the `seed` property to ensure traffic is split consistently for a given context value irrespective of where the split operator is used. If you don't specify `seed`, the hash is *locally* consistent, meaning traffic will be split consistently for that flag, but other flags receiving the same context value may split traffic differently. If `seed` is provided, each unique value is guaranteed to split traffic consistently across feature flags, configuration profiles, and AWS accounts.

Typically, customers use the same `seed` value across variants within a flag when splitting traffic on the same context property. However, it may occasionally make sense to use a different seed value. Here is an example that uses different seeds for rules A and B:

```
A: (split by::$uniqueId pct::20 seed::"seed_one")
B: (split by::$uniqueId pct::25 seed::"seed_two")
C: <default>
```

As before, 20% of the matching `uniqueId` values match rule A. That means 80% of values fall through and are tested against variant rule B. Because the seed is different, there is no correlation between the values that matched A and the values that match B. There are, however, only 80% as many `uniqueId` values to split with 25% of that number matching rule B and 75% not. That works out to the following distribution:

```
A: 20%
B: 20% (25% of what falls through from A, or 25% of 80%) 
C: 60%
```

# Creating a multi-variant feature flag


Use the procedures in this section to create variants of a feature flag.

**Before you begin**  
Note the following important information.
+ You can create variants of existing feature flags by editing them. You can't create variants of a new feature flag *when you create a new configuration profile*. You must complete the workflow of creating the new configuration profile first. After you create the configuration profile, you can add variants to any flag within the configuration profile. For information about how to create a new configuration profile, see [Creating a feature flag configuration profile in AWS AppConfig](appconfig-creating-configuration-and-profile-feature-flags.md).
+ To retrieve feature flag variant data for Amazon EC2, Amazon ECS, and Amazon EKS compute platforms, you must use AWS AppConfig Agent version 2.0.4416 or later.
+ For performance reasons, AWS CLI and SDK calls to AWS AppConfig don't retrieve variant data. For more information about AWS AppConfig Agent, see [How to use AWS AppConfig Agent to retrieve configuration data](appconfig-agent-how-to-use.md).
+ When you create a feature flag variant, you specify a rule for it. Rules are expressions that take request context as input and produce a boolean result as output. Before you create variants, review the supported operands and operators for flag variant rules. You can create rules before you create variants. For more information, see [Understanding multi-variant feature flag rules](appconfig-creating-multi-variant-feature-flags-rules.md).

**Topics**
+ [

## Creating a multi-variant feature flag (console)
](#appconfig-creating-multi-variant-feature-flags-procedures-console)
+ [

## Creating a multi-variant feature flag (command line)
](#appconfig-creating-multi-variant-feature-flags-procedures-commandline)

## Creating a multi-variant feature flag (console)


The following procedure describes how to create a multi-variant feature flag for an existing configuration profile by using the AWS AppConfig console. You can also edit existing feature flags to create variants.

**To create a multi-variant feature flag**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/appconfig/](https://console.aws.amazon.com/systems-manager/appconfig/).

1. In the navigation pane, choose **Applications**, and then choose an application.

1. On the **Configuration profiles and feature flags** tab, choose an existing feature flag configuration profile.

1. In the **Flags** section, choose **Add new flag**.

1. In the **Feature flag definition** section, for **Flag name**, enter a name.

1. For **Flag key** enter a flag identifier to distinguish flags within the same configuration profile. Flags within the same configuration profile can't have the same key. After the flag is created, you can edit the flag name, but not the flag key. 

1. (Optional) In the **Description** field, enter information about this flag.

1. In the **Variants** section, choose **Multi-variant flag**.

1. (Optional) In the **Feature flag attributes** section, choose **Define attribute**. Attributes enable you to provide additional values within your flag. For more information about attributes and constraints, see [Understanding feature flag attributes](appconfig-creating-configuration-and-profile-feature-flags.md#appconfig-creating-configuration-profile-feature-flag-attributes).

   1. For **Key**, specify a flag key and choose its type from the **Type** list. For information about the supported options for the **Value** and **Constraints** fields, see the previously referenced section about attributes.

   1. Select **Required value** to specify whether an attribute value is required.

   1. Choose **Define attribute** to add additional attributes.

   1. Choose **Apply** to save attribute changes.

1. In the **Feature flag variants** section, choose **Create variant**.

   1. For **Variant name**, enter a name.

   1. Use the **Enabled value** toggle to enable the variant.

   1. In the **Rule** text box, enter a rule.

   1. Use the **Create variant** > **Create variant above** or **Create variant below** options to create additional variants for this flag. 

   1. In the **Default variant** section, use the **Enabled value** toggle to enable the default variant. Optionally, provide values for attributes defined in step 10.

   1. Choose **Apply**.

1. Verify the details of the flag and its variants and choose **Create flag**.

For information about deploying your new feature flag with variants, see [Deploying feature flags and configuration data in AWS AppConfig](deploying-feature-flags.md).

## Creating a multi-variant feature flag (command line)


The following procedure describes how to use the AWS Command Line Interface (on Linux or Windows) or Tools for Windows PowerShell to create a multi-variant feature flag for an existing configuration profile. You can also edit existing feature flags to create variants.

**Before you begin**  
Complete the following tasks before you create a multi-variant feature flag by using the AWS CLI.
+ Create a feature flag configuration profile. For more information, see [Creating a feature flag configuration profile in AWS AppConfig](appconfig-creating-configuration-and-profile-feature-flags.md).
+ Update to the latest version of the AWS CLI. For more information, see [Install or update to the latest version of the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) in the *AWS Command Line Interface User Guide*.

**To create a multi-variant feature flag**

1. Create a configuration file on your local machine that specifies the details of the multi-variant flag you want to create. Save the file with a `.json` file extension. The file must adhere to the [https://docs.aws.amazon.com/appconfig/latest/userguide/appconfig-type-reference-feature-flags.html](https://docs.aws.amazon.com/appconfig/latest/userguide/appconfig-type-reference-feature-flags.html) JSON schema. The schema contents of your configuration file will be similar to the following.

   ```
   {
     "flags": {
       "FLAG_NAME": {
         "attributes": {
             "ATTRIBUTE_NAME": {
             "constraints": {
               "type": "CONSTRAINT_TYPE"
             }
           }
         },
         "description": "FLAG_DESCRIPTION",
         "name": "VARIANT_NAME"
       }
     },
     "values": {
       "VARIANT_VALUE_NAME": {
         "_variants": [
           {
             "attributeValues": {
               "ATTRIBUTE_NAME": BOOLEAN
             },
             "enabled": BOOLEAN,
             "name": "VARIANT_NAME",
             "rule": "VARIANT_RULE"
           },
           {
             "attributeValues": {
               "ATTRIBUTE_NAME": BOOLEAN
             },
             "enabled": BOOLEAN,
             "name": "VARIANT_NAME",
             "rule": "VARIANT_RULE"
           },
           {
             "attributeValues": {
               "ATTRIBUTE_NAME": BOOLEAN
             },
             "enabled": BOOLEAN,
             "name": "VARIANT_NAME",
             "rule": "VARIANT_RULE"
           },
           {
             "attributeValues": {
               "ATTRIBUTE_NAME": BOOLEAN
             },
             "enabled": BOOLEAN,
             "name": "VARIANT_NAME",
             "rule": "VARIANT_RULE"
           }
         ]
       }
     },
     "version": "VERSION_NUMBER"
   }
   ```

   Here is an example with three variants and the default variant.

   ```
   {
     "flags": {
       "ui_refresh": {
         "attributes": {
           "dark_mode_support": {
             "constraints": {
               "type": "boolean"
             }
           }
         },
         "description": "A release flag used to release a new UI",
         "name": "UI Refresh"
       }
     },
     "values": {
       "ui_refresh": {
         "_variants": [
           {
             "attributeValues": {
               "dark_mode_support": true
             },
             "enabled": true,
             "name": "QA",
             "rule": "(ends_with $email \"qa-testers.mycompany.com\")"
           },
           {
             "attributeValues": {
               "dark_mode_support": true
             },
             "enabled": true,
             "name": "Beta Testers",
             "rule": "(exists key::\"opted_in_to_beta\")"
           },
           {
             "attributeValues": {
               "dark_mode_support": false
             },
             "enabled": true,
             "name": "Sample Population",
             "rule": "(split pct::10 by::$email)"
           },
           {
             "attributeValues": {
               "dark_mode_support": false
             },
             "enabled": false,
             "name": "Default Variant"
           }
         ]
       }
     },
     "version": "1"
   }
   ```

1. Use the `CreateHostedConfigurationVersion` API to save your feature flag configuration data to AWS AppConfig.

------
#### [ Linux ]

   ```
   aws appconfig create-hosted-configuration-version \
     --application-id APPLICATION_ID \
     --configuration-profile-id CONFIGURATION_PROFILE_ID \
     --content-type "application/json" \
     --content file://path/to/feature_flag_configuration_data.json \
     --cli-binary-format raw-in-base64-out \
     outfile
   ```

------
#### [ Windows ]

   ```
   aws appconfig create-hosted-configuration-version ^
     --application-id APPLICATION_ID ^
     --configuration-profile-id CONFIGURATION_PROFILE_ID ^
     --content-type "application/json" ^
     --content file://path/to/feature_flag_configuration_data.json ^
     --cli-binary-format raw-in-base64-out ^
     outfile
   ```

------
#### [ PowerShell ]

   ```
   New-APPCHostedConfigurationVersion `
     -ApplicationId APPLICATION_ID `
     -ConfigurationProfileId CONFIGURATION_PROFILE_ID `
     -ContentType "application/json" `
     -Content file://path/to/feature_flag_configuration_data.json `
     -Raw
   ```

------

   The `service_returned_content_file` contains your configuration data that includes some AWS AppConfig generated metadata.
**Note**  
When you create the hosted configuration version, AWS AppConfig verifies that your data conforms to the [https://docs.aws.amazon.com/appconfig/latest/userguide/appconfig-type-reference-feature-flags.html](https://docs.aws.amazon.com/appconfig/latest/userguide/appconfig-type-reference-feature-flags.html) JSON schema. AWS AppConfig additionally validates that each feature flag attribute in your data satisfies the constraints you defined for those attributes.

# Understanding the type reference for AWS.AppConfig.FeatureFlags


Use the `AWS.AppConfig.FeatureFlags` JSON schema as a reference to create your feature flag configuration data.

```
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "flagSetDefinition": {
      "type": "object",
      "properties": {
        "version": {
          "$ref": "#/definitions/flagSchemaVersions"
        },
        "flags": {
          "$ref": "#/definitions/flagDefinitions"
        },
        "values": {
          "$ref": "#/definitions/flagValues"
        }
      },
      "required": ["version"],
      "additionalProperties": false
    },
    "flagDefinitions": {
      "type": "object",
      "patternProperties": {
        "^[a-z][a-zA-Z\\d_-]{0,63}$": {
          "$ref": "#/definitions/flagDefinition"
        }
      },
      "additionalProperties": false
    },
    "flagDefinition": {
      "type": "object",
      "properties": {
        "name": {
          "$ref": "#/definitions/customerDefinedName"
        },
        "description": {
          "$ref": "#/definitions/customerDefinedDescription"
        },
        "_createdAt": {
          "type": "string"
        },
        "_updatedAt": {
          "type": "string"
        },
        "_deprecation": {
          "type": "object",
          "properties": {
            "status": {
              "type": "string",
              "enum": ["planned"]
            },
            "date": {
              "type": "string",
              "format": "date"
            }
          },
         "additionalProperties": false
        },
        "attributes": {
          "$ref": "#/definitions/attributeDefinitions"
        }
      },
      "additionalProperties": false
    },
    "attributeDefinitions": {
      "type": "object",
      "patternProperties": {
        "^[a-z][a-zA-Z\\d_-]{0,63}$": {
          "$ref": "#/definitions/attributeDefinition"
        }
      },
      "maxProperties": 25,
      "additionalProperties": false
    },
    "attributeDefinition": {
      "type": "object",
      "properties": {
        "description": {
          "$ref": "#/definitions/customerDefinedDescription"
        },
        "constraints": {
          "oneOf": [
            { "$ref": "#/definitions/numberConstraints" },
            { "$ref": "#/definitions/stringConstraints" },
            { "$ref": "#/definitions/arrayConstraints" },
            { "$ref": "#/definitions/boolConstraints" }
          ]
        }
      },
      "additionalProperties": false
    },
    "flagValues": {
      "type": "object",
      "patternProperties": {
        "^[a-z][a-zA-Z\\d_-]{0,63}$": {
          "$ref": "#/definitions/flagValue"
        }
      },
      "additionalProperties": false
    },
    "flagValue": {
      "type": "object",
      "properties": {
        "enabled": {
          "type": "boolean"
        },
        "_createdAt": {
          "type": "string"
        },
        "_updatedAt": {
          "type": "string"
        },
        "_variants": {
          "type": "array",
          "maxLength": 32,
          "items": {
            "$ref": "#/definitions/variant"
          }
        }
      },
      "patternProperties": {
        "^[a-z][a-zA-Z\\d_-]{0,63}$": {
          "$ref": "#/definitions/attributeValue",
          "maxProperties": 25
        }
      },
      "additionalProperties": false
    },
    "attributeValue": {
      "oneOf": [
        { "type": "string", "maxLength": 1024 },
        { "type": "number" },
        { "type": "boolean" },
        {
          "type": "array",
          "oneOf": [
            {
              "items": {
                "type": "string",
                "maxLength": 1024
              }
            },
            {
              "items": {
                "type": "number"
              }
            }
          ]
        }
      ],
      "additionalProperties": false
    },
    "stringConstraints": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string",
          "enum": ["string"]
        },
        "required": {
          "type": "boolean"
        },
        "pattern": {
          "type": "string",
          "maxLength": 1024
        },
        "enum": {
          "type": "array",
          "maxLength": 100,
          "items": {
            "oneOf": [
              {
                "type": "string",
                "maxLength": 1024
              },
              {
                "type": "integer"
              }
            ]
          }
        }
      },
      "required": ["type"],
      "not": {
        "required": ["pattern", "enum"]
      },
      "additionalProperties": false
    },
    "numberConstraints": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string",
          "enum": ["number"]
        },
        "required": {
          "type": "boolean"
        },
        "minimum": {
          "type": "integer"
        },
        "maximum": {
          "type": "integer"
        }
      },
      "required": ["type"],
      "additionalProperties": false
    },
    "arrayConstraints": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string",
          "enum": ["array"]
        },
        "required": {
          "type": "boolean"
        },
        "elements": {
          "$ref": "#/definitions/elementConstraints"
        }
      },
      "required": ["type"],
      "additionalProperties": false
    },
    "boolConstraints": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string",
          "enum": ["boolean"]
        },
        "required": {
          "type": "boolean"
        }
      },
      "required": ["type"],
      "additionalProperties": false
    },
    "elementConstraints": {
      "oneOf": [
        { "$ref": "#/definitions/numberConstraints" },
        { "$ref": "#/definitions/stringConstraints" }
      ]
    },
    "variant": {
      "type": "object",
      "properties": {
        "enabled": {
          "type": "boolean"
        },
        "name": {
          "$ref": "#/definitions/customerDefinedName"
        },
        "rule": {
          "type": "string",
          "maxLength": 16384
        },
        "attributeValues": {
          "type": "object", 
          "patternProperties": {
            "^[a-z][a-zA-Z\\d_-]{0,63}$": {
              "$ref": "#/definitions/attributeValue"
            }
          },
          "maxProperties": 25,
          "additionalProperties": false
        }
      },
      "required": ["name", "enabled"],
      "additionalProperties": false
    },
    "customerDefinedName": {
      "type": "string",
      "pattern": "^[^\\n]{1,64}$"
    },
    "customerDefinedDescription": {
      "type": "string",
      "maxLength": 1024
    },
    "flagSchemaVersions": {
      "type": "string",
      "enum": ["1"]
    }
  },
  "type": "object",
  "$ref": "#/definitions/flagSetDefinition",
  "additionalProperties": false
}
```

**Important**  
To retrieve feature flag configuration data, your application must call the `GetLatestConfiguration` API. You can't retrieve feature flag configuration data by calling `GetConfiguration`, which is deprecated. For more information, see [GetLatestConfiguration](https://docs.aws.amazon.com/appconfig/2019-10-09/APIReference/API_GetLatestConfiguration.html) in the *AWS AppConfig API Reference*.

When your application calls [GetLatestConfiguration](https://docs.aws.amazon.com/appconfig/2019-10-09/APIReference/API_GetLatestConfiguration.html) and receives a newly deployed configuration, the information that defines your feature flags and attributes is removed. The simplified JSON contains a map of keys that match each of the flag keys you specified. The simplified JSON also contains mapped values of `true` or `false` for the `enabled` attribute. If a flag sets `enabled` to `true`, any attributes of the flag will be present as well. The following JSON schema describes the format of the JSON output.

```
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "patternProperties": {
    "^[a-z][a-zA-Z\\d_-]{0,63}$": {
      "$ref": "#/definitions/attributeValuesMap"
    }
  },
  "additionalProperties": false,
  "definitions": {
    "attributeValuesMap": {
      "type": "object",
      "properties": {
        "enabled": {
          "type": "boolean"
        }
      },
      "required": ["enabled"],
      "patternProperties": {
        "^[a-z][a-zA-Z\\d_-]{0,63}$": {
          "$ref": "#/definitions/attributeValue"
        }
      },
      "maxProperties": 25,
      "additionalProperties": false
    },
    "attributeValue": {
      "oneOf": [
        { "type": "string","maxLength": 1024 },
        { "type": "number" },
        { "type": "boolean" },
        {
          "type": "array",
          "oneOf": [
            {
              "items": {
                "oneOf": [
                  {
                    "type": "string",
                    "maxLength": 1024
                  }
                ]
              }
            },
            {
              "items": {
                "oneOf": [
                  {
                    "type": "number"
                  }
                ]
              }
            }
          ]
        }
      ],
      "additionalProperties": false
    }
  }
}
```

# Saving a previous feature flag version to a new version


When you update a feature flag, AWS AppConfig automatically saves your changes to a new version. If you want to use a previous feature flag version, you must copy it to a draft version and then save it. You can't edit and save changes to a previous flag version without saving it to a new version. 

**To edit a previous feature flag version and save it to a new version**

1. Open the AWS Systems Manager console at [https://console.aws.amazon.com/systems-manager/appconfig/](https://console.aws.amazon.com/systems-manager/appconfig/).

1. In the navigation pane, choose **Applications**, and then choose the application with the feature flag you want to edit and save to a new version.

1. On the **Configuration profiles and feature flags** tab, choose the configuration profile with the feature flag you want to edit and save to a new version.

1. On the **Feature flags** tab, use the **Version** list to choose the version you want to edit and save to a new version.

1. Choose **Copy to draft version**.

1. In the **Version label** field, enter a new label (optional, but recommended).

1. In the **Version description** field, enter a new description (optional, but recommended).

1. Choose **Save version**.

1. Choose **Start deployment** to deploy the new version.