Getting Started with FlagOps
FlagOps allows you to integrate feature flagging into your GitOps deployments giving easier control over feature rollouts and configuration. In this guide, I will walk you through setting up a basic GitOps project using Helm, ArgoCD, and FlagOps to be able to orchestrate your deployments with feature flags. You can read more about the background of FlagOps here
Prerequisites
To follow this guide you will need:
- A kubernetes cluster - Can be kind, bare metal, or hosted on a cloud provider.
- ArgoCD deployed - Follow this guide
- A Flagsmith Account - We will use this to create and manage our feature flags.
- Basic knowledge of kubernetes and ArgoCD
Setting up the ArgoCD Plugins
The first thing we need to do is install the FlagOps ArgoCD Plugin. The plugin will take our templates from our repository, inject our feature flags as template variables, and then output the resulting files to be applied to the cluster. The manifests for the installation are available in the repo.
Before we apply the manifests we will need to modify the environment configuration under cmp-plugin.yaml
.
apiVersion: v1
kind: ConfigMap
metadata:
name: flagops-env
data:
flagops-env.yaml: |
envs:
production:
provider: flagsmith
apiKey: <api-key>
staging:
provider: flagsmith
apiKey: <api-key>
Here we will replace the <api-key>
with the Flagsmith client sdk keys which can be found in the dashboard under SDK Keys
.
Once we have added these keys we can apply the configurations by running kustomize apply -k .
in the manifests directory.
You should now see in your k8s cluster that the ArgoCD repo server has 3 new containers that will run our plugin code.
Setting Up the GitOps Repo
Now that ArgoCD can accept a repository with feature flags we need to create a repo for it to sync with. You can use the example setup repository here. I recommend copying this repository and using it as a base to experiment with FlagOps.
This example repo has a single application set that passes which is set up to take all the directories under /apps
and try to apply them as helm charts by using the FlagOps plugin.
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: nginx-app
namespace: argocd
spec:
goTemplate: true
goTemplateOptions: ['missingkey=error']
generators:
- matrix:
generators:
- git:
repoURL: https://github.com/graytonio/flagops-argocd-example.git
revision: HEAD
directories:
- path: apps/*
# These are example clusters that we can use to create rules around our flags.
- list:
elements:
- cluster: flagops-dev-use
url: https://kubernetes.default.svc
- cluster: flagops-dev-usc
url: https://kubernetes.default.svc
- cluster: flagops-dev-usw
url: https://kubernetes.default.svc
template:
metadata:
name: '{{.path.basename}}-{{.cluster}}'
spec:
project: 'demo'
source:
repoURL: https://github.com/graytonio/flagops-argocd-example.git
targetRevision: HEAD
path: '{{.path.path}}'
plugin:
name: flagops-plugin-helm
env:
- name: FLAGOPS_ENVIRONMENT
value: testing
- name: FLAGOPS_PROP_OWNER
value: graytonw
- name: FLAGOPS_PROP_CLUSTER
value: '{{.cluster}}'
destination:
server: '{{.url}}'
namespace: '{{.path.basename}}-{{.cluster}}'
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
The application we have configured is a simple NGINX web server with 2 important feature flags instrumented in the values.yaml
file.
nginx:
# The first feature flag "nginx_replicas" controls how many pods our deployment will be running.
replicaCount: [{ env "nginx_replicas" }]
# This feature flag "demo_app" controls if the pod should clone the example application before launching.
[{- if env "demo_app_enabled" }] # The flag is using the "_enabled" syntax to look up a flag called "demo_app" and parse it as a boolean
cloneStaticSiteFromGit:
enabled: true
repository: https://github.com/mdn/beginner-html-site-styled.git
branch: master
[{- end }]
In the next section, we will create these feature flags in Flagsmith so that we can control both of these parameters from the dashboard.
Creating the Feature Flags
The last step before we can deploy our applications to ArgoCD is we need to create the feature flags in the Flagsmith dashboard.
The first flag nginx_replicas
can be created with a default value of 1
And the second flag demo_app
does not need a default value.
Deploying the app
Now that all the setup is done we can finally connect ArgoCD to our GitOps repository. We will add an application and configure it to pull the manifests from our repository by clicking on the New App
button in our dashboard. For this example we will use the example repo which deploys 3 nginx web servers with some associated metadata to show off how we can take advantage of FlagOps.
You can copy and paste the yaml here to add the FlagOps demo repository as an application in ArgoCD.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: flagops
spec:
destination:
name: ''
namespace: flagops
server: 'https://kubernetes.default.svc'
source:
path: root/
repoURL: 'https://github.com/graytonio/flagops-argocd-example.git'
targetRevision: HEAD
sources: []
project: demo
syncPolicy:
automated:
prune: true
selfHeal: true
You should see that the root application is created along with the three deployments of NGINX for each of our configured “clusters”.
Controlling Features
Now that it is deployed we can go back to our dashboard and start updating some features. First let’s start by updating how many replicas we want to be running. We can go to the features section, select our nginx_replicas
feature, and update the value to 3.
Once we do this we can wait for ArgoCD to automatically Hard Refresh the app or we can manually hard refresh it to apply the changes now. And once the app refreshes we should see that each application now has 3 replicas of NGINX.
Now we want to change only one application’s values without changing them all. We can do this by going to our identities page and choosing one of our applications to update. You’ll see each identity matches up with an application and has some traits that help us get some information about the deployment.
These are some basic examples but they can be easily expanded through the appset.
We can select the nginx_replicas
again and update the value for this application to 5.
After saving and refreshing we should see again that only the application we picked was scaled up to 5 replicas.
This is all great but the real power is when we start applying rules with Segments. Segments are a tool in Flagsmith that allows you to override feature flag values based on rules about the traits we saw earlier. We won’t be going too far in depth about segments right now but if you want to learn more you can read the documentation.
For our purposes, we want to create a segment which any application deployed in a certain region will have the demo_app
feature disabled. First, we need to create a new segment and add a rule for the cluster to be a specific value. The “clusters” that the applications are in can be found in their identities.
Once it has been created we can update our production overrides to disable the demo_app
feature.
Once again after saving and refreshing, you can see that the application in the region we specified does not have the repo sync container like the other ones do.
Next Steps
This has been a very basic setup for applying FlagOps to your deployment system but it can be extended to much more complex setups depending on your organization’s needs. If you need help with any kind of setup feel free to open an issue to the FlagOps repo.