Configuration as Code

Configuration as Code (CAC) allows the entire configuration of CloudBees Feature Flags to be stored as source code. It integrates the CloudBees Feature Flags UI with your existing environment. This approach brings a lot of benefits.

Experiments have been deprecated and Flags are the only entity in the system

  • Config as Code will still be using the experiments terminology for now.

  • When creating a Flag in the code or dashboard, it would only be created in the Config as Code YAML file when at least one change is made to the flag on the specific environment.

Activating Configuration as Code

CAC module is backed with the CloudBees Feature Flags code management service integrations, when enabled, CloudBees Feature Flags syncs its data to and from your repository.

Your repository is the source of truth

CloudBees Feature Flags integration with Git code management service includes a bi-directional connection with your repository.

If you make changes in your repository and push it to the remote origin branch, CloudBees Feature Flags will pick these updates and update the dashboard accordingly.

If you make changes in the dashboard, the CloudBees Feature Flags system will push commits into your branches.

Connecting to GitHub Cloud

CloudBees Feature Flags leverages GitHub apps to allow the integration and minimize permission into just the required repository. CloudBees Feature Flags does not have any access (no read and no write) to your code. Only access to the repository that contains CloudBees Feature Flags data.

  1. Create an empty repository on GitHub.

  2. Connect the CloudBees Feature Flags app to the Github repository.

    1. Go to App Settings > Integrations tab (from the left Panel).

    2. Click the connect button.

      Integration app with github

  3. In GitHub, select to integrate the CloudBees Feature Flags GitHub app with your created repository.

    Integrate app with repo

  4. After clicking Install, you will be redirected back to the CloudBees Feature Flags dashboard to select your app and the repository.

    Connect app into repo

  5. Click connect and you are done

Connecting to GitHub Enterprise

In order to enable the connection of CloudBees Feature Flags to GitHub Enterprise, you will need to create a GitHub application that allows CloudBees Feature Flags to connect to it.

Please contact the CloudBees Feature Flags team for a walkthrough session.

Connecting to Bitbucket

Bitbucket integration is currently being developed, please let us know if you want to join the early adopters (email us at support@rollout.io).

Repository, Directories and YAML structure

Branches are environments

Every environment on the CloudBees Feature Flags dashboard is mapped to a branch in Git. The same name that is used for the environment will be used for the branch name. The only exception being the Production environment which is mapped to master branch.

Directory structure

The repository integration creates the following directory structure:

.
├── experiments             # Experiments definitions
│   └──  archived           # Archived experiments definitions
├── target_groups           # Target groups definitions
└── README.md
  • All Experiments are located under the Experiment folder

  • All archived Experiments are located under the experiments/archived folder

Experiment examples

False for all users

flag: default.followingView
type: experiment
name: following view
value: false

The following is the YAML representation in the dashboard:

YAML false all users

50% split

flag: default.followingView
type: experiment
name: following view
value:
  - option: true
    percentage: 50

The following is the YAML representation in the dashboard:

YAML fifty split

Open feature for QA and Beta Users on version 3.0.1, otherwise close it

flag: default.followingView
type: experiment
name: following view
conditions:
  - group:
      name:
        - QA
        - Beta Users
    version:
      operator: semver-gte
      semver: 3.0.1
    value: true
value: false

The following is the YAML representation in the dashboard:

YAML version

Open feature for all platforms, excluding Android

flag: default.followingView
type: experiment
name: following view
platforms:
  - name: Android
    value: false
value: true

The following is the default platform configuration in the dashboard:

YAML default

The following is the Android configuration in the dashboard:

YAML android

Experiment YAML

This section describes the YAML scheme for an Experiment. It is a composite of 3 schemas:

  • Root schema - the base schema for experiment

  • Split value schema - Represents a split value - a value that is distributed among different instances based on percentage

  • Scheduled value schema - Represents a scheduled value - a value that is based on the time that the flag was evaluated

  • Condition schema - Specify how to target a specific audience/device

  • Platform schema - Specify how to target a specific platform

Root schema

An Experiment controls the flag value in runtime:

# Yaml api version
# Optional: defaults to "1.0.0"
apiVersion: Semver

# Yaml Type (required)
type: "experiment"

# The flag being controlled by this experiment (required)
flag: String

# The available values that this flag can be
# Optional=[false, true]
availableValues: [String|Bool]

# The name of the experiment
# Optional: default flag name
name: String

# The Description of the experiment
# Optional=""
description: String

# Indicates if the experiment is active
# Optional=true
enabled: Boolean

# Expriment lables
# Optional=[]
labels: [String]|String

# Stickiness property that controls percentage based tossing
# Optional="rox.distict_id"
stickinessProperty: String

# Platform explicit targeting
# Optional=[]
platforms: [Platform]  # see Platform schema

# Condition and values for default platform
# Optional=[]
conditions: [Condition] # see Condition schema

# Value when no Condition is met
# Optional
#  false for boolean flags
#  null for enum flags  (indicates default value)
value: String|Boolean|[SplitedValue]|[ScheduledValue]

Split value schema

# Percentage, used for splitting traffic across different values (required)
percentage: Number

# The Value to be delivered (required)
option: String|Boolean

Scheduled value schema

# The Date from which this value is relevant (required)
from: Date

# Percentage, used for splitting traffic across different values  (required)
percentage: Number

# The Value to be delivered (required)
option: Boolean

Scheduled value is only supported for boolean flags

Scheduled Value is supported only for boolean flags, you can’t use them for Variant flags.

Condition schema

The Condition is a pair of condition and value, an array of conditions can be viewed as an if-else statement by the order of conditions.

The schema contains three types of condition statements.

  • Dependency - express flag dependencies, by indicating flag name and expected value

  • Groups - a list of target-groups and the operator that indicates the relationship between them (or|and|not)

  • Property - a single property, the operator and operand (very similar to Target groups' condition)

  • Version - comparing the version of

Select either Flag Dependency, Target Group, or Property

Although it is valid DSL structure, the CloudBees Feature Flags toolchain does not support combined Condition types. Therefore each condition can only include one Target Group, Flag Dependency, or Property.

If you require combined condition types, please reach out to CloudBees to submit a feature request.

The relationship between these items is and, meaning: If the dependency is met and Groups matches and Property matches and Version matches then flag=value.

Here is the Condition schema:

# Condition this flag value with another flag value
dependency:
    # Flag Name
    flag: String
    # The expected Flag Value
    value: String|Boolean

# Condition flag value based on target group(s)
group:
    # The logical relationship between the groups
    # Optional = or
    operator: or|and|not

    # Name of target groups
    name: [String]|String

# Condition flag value based on a single property
property:
          # The Custom property Name to be conditioned
          name: String

          # The Operator of the confition
          operator: is-undefined|is-true|is-false|eq|ne|gte|gt|lt|lte|regex|semver-gt|semver-eq|semver-gte|semver-gt|semver-lt|semver-lte

          # The Second operand of the condition
          # Optional - Based on operator  (is-undefined, is-true, is-false)
          operand: String|Number|[String]

# Condition flag value based release version
version:
    # The operator to compare version
    operator: semver-gt|semver-gte|semver-eq|semver-ne|semver-lt|semver-lte

    # The version to compare to
    semver: Semver

# Value when Condition is met
value: String|Boolean|[SplitedValue]|[ScheduledValue]

Platform schema

The platform object indicates a specific targeting for a specific platform.

# Name of the platform, as defined in the SDK running
name: String

# Override the flag name, when needed
# Optional = experiment flag name
flag: String

# Condition and values for default platform
# Optional=[]
conditions: [Condition] # see Condition schema

# Value when no Condition is met
# Optional
#  false for boolean flags
#  null for enum flags  (indicates default value)
value: String|Boolean|[SplitedValue]|[ScheduledValue] # see Value schema

Target Group Examples

List of matching userid

type: target-group
name: QA
conditions:
  - operator: in-array
    property: soundcloud_id
    operand:
      - 5c0588007cd291cca474454f
      - 5c0588027cd291cca4744550
      - 5c0588037cd291cca4744551
      - 5c0588047cd291cca4744552
      - 5c0588047cd291cca4744553

Target group userid

Using number property for comparison

type: target-group
name: DJ
operator: or
conditions:
  - operator: gte
    property: playlist_count
    operand: 100
description: Users with a lot of playlists

In Dashboard:

Target group playlist

Target Group YAML

A Target group is a set of rules on top of custom properties that are defined in runtime, it is used in experiment conditions.

# Yaml api version
# Optional: defaults to "1.0.0"
version: Semver

# Yaml Type (required)
type: "target-group"

#Target Group Name
name: String

# Target Group description
# Optional = ""
description: String

# The logical relationship between conditions
# Optional = and
operator: or|and

# Array of Conditions that have a logical AND relationship between them
conditions:
    # The Custom property to be conditioned (first operand)
  - property: String

    # The Operator of the confition
    operator: is-undefined|is-true|is-false|eq|ne|gte|gt|lt|lte|regex|semver-gt|semver-eq|semver-gte|semver-gt|semver-lt|semver-lte

    # The Second operand of the condition
    # Optional - Based on operator  (is-undefined, is-true, is-false)
    operand: String|Number|[String]

Advantages of Configuration as Code

Versioning of changes

You can store the CAC in a version control system, such as Git, to see who changed what and when in your production environment. You can use tags to mark specific version. You can use branches to isolate changes to rollback in time and to work in parallel streams without affecting your production/Staging environment.

Traceability of changes

You can track which changes have been applied to your production environment. Analyzing configuration differences (e.g. via git diff) is quite often more convenient and efficient than reading audit logs in the CloudBees Feature Flags dashboard.

Automation

CAC is written as source code and is tied into git operations so you can use all development and release best practices to integrate feature delivery into your deployment and release pipelines. You can add tools like automated testing, altering target groups based on production data, copying definitions from other apps. The YAML interface along with the CloudBees Feature Flags library allows your engineering team to extend the system based on their needs.

Smooth promotion of changes from test to production

CloudBees Feature Flags uses a git branch for each environment e.g. production, staging, development. Promoting changes from these environments using git native merging or GitHub pull request is simpler than clicking through many UI pages, testing that everything works and next tediously repeating the same steps on the production instance. With configuration as code you can simply deploy plans to a test instance, verify changes and then deploy to the production instance just by merging back the code.

Microservices oriented development and testing

Engineers have the ability to work in an isolated manner both for local development and testing environments by utilizing a local copy of the CloudBees Feature Flags configuration combined with the CloudBees Feature Flags Roxy Docker image. Roxy replaces CloudBees Feature Flags storage and runs from inside your domain. In practice it supplies a mock service on top of CloudBees Feature Flags software as a service solution. See Microservices automated testing and local development for more information.