Cloud native feature-flagging with the OpenFeature Operator
In the following tutorial, we'll see how to leverage flagd and the OpenFeature Operator to enable cloud-native, self-hosted feature flags in your Kubernetes cluster. flagd is a "feature flag daemon with a Unix philosophy". Put another way, it's a small, self-contained binary that evaluates feature flags, uses standard interfaces, and runs just about anywhere. It can be deployed in a central location serving multiple clients or embedded into a unit of deployment (such as a pod in Kubernetes). The OpenFeature Operator is a K8s-flavored solution for easily adding flagd to any relevant workloads. It parses Kubernetes spec files and adds flagd and associated objects to the workloads based on annotations and custom resource definitions it understands.
Let's do it
- If you don't have access to an existing K8s cluster, you have a few options:
- kind is similar to minikube (another solution for running a cluster locally you may be familiar with) but supports more than one node, so it makes for a slightly more realistic experience. If using kind, this tutorial provides a 3-node cluster definition with a forwarded containerPort for you (more on that later).
- MicroK8s and K3s are easily installable Kubernetes clusters you can use locally.
The benefit of these is that they are the basically identical to a production environment.
K3sis out of the scope of this tutorial.
- k9s (optional, if you'd like to inspect your cluster visually)
Show me the commands
Download the file defining our demo deployment, service, and CRD,
curl -sfL curl -sfL https://raw.githubusercontent.com/open-feature/playground/main/config/k8s/end-to-end.yaml > end-to-end.yaml
Building our cluster
OK, let's get our cluster up and running! If you already have a K8s cluster, you can skip to Install cert-manager.
Download the cluster definition file,
curl -sfL curl -sfL https://raw.githubusercontent.com/open-feature/docs.openfeature.dev/main/static/samples/kind-cluster.yaml > kind-cluster.yaml
Then, create our cluster using the
kind create cluster --config kind-cluster.yaml
This might take a minute or two.
Great! Next, because our operator makes use of webhooks, we need some certificate infrastructure in our cluster. If your cluster already has cert manager, or you're using another solution for certificate management, you can skip to Create Namespace.
Install cert-manager, and wait for it to be ready:
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.9.1/cert-manager.yaml && \
kubectl wait --timeout=60s --for condition=Available=True deploy --all -n 'cert-manager'
Next, we need to create a namespace for the operator and our workload:
kubectl create namespace open-feature-operator-system
Install OpenFeature operator
And finally, let's install the operator itself:
kubectl apply -f https://github.com/open-feature/open-feature-operator/releases/download/v0.2.29/release.yaml && \
kubectl wait --timeout=60s --for condition=Available=True deploy --all -n 'open-feature-operator-system'
Deploy our workload
Now that the operator is ready to go, we can deploy our workload:
kubectl -n default apply -f end-to-end.yaml && \
kubectl wait --timeout=60s deployment --for condition=Available=True -l 'app=open-feature-demo' -n 'default'
If you're using
k9s or some other means of visualization, your cluster should look something like this:
Forward the service
If you're using the supplied
kind config, you can skip to Experiment with OpenFeature, this port is already forwarded.
Forward the service port:
kubectl port-forward svc/open-feature-demo-service -n default 30000:30000
Experiment with OpenFeature
Now you should see our fictional app at http://localhost:30000
For this demo, we get flag definitions from the custom resource definition you applied to K8s above (
The resource type is
FeatureFlagconfiguration and is called
end-to-end within the
You can modify the flag values in the
featureFlagSpec and reapply the CRD to see the changes.
This file also contains service and deployment definitions, but these need not be modified as part of this demo.
You may be interested in the
openfeature.dev* annotations though, which the OpenFeature operator uses to detect which workloads require flagd.
Let's get started learning how OpenFeature is helping Fib3r manage this landing page!
The company has been in the process of changing the name of our app, but legal hasn't quite finished the process yet.
Here, we've defined a simple feature flag that can be use to update the name instantly without redeploying our application.
"defaultVariant" of the feature flag
"on" in the
featureFlagSpec, then redeploy the change with:
kubectl apply -n default -f end-to-end.yaml
Now let's help the design team experiment with new color palette.
Let's change our landing page's color.
"defaultVariant" of the
"hex-color" within the
end-to-end.yaml file and use
kubectl to apply the change again.
Flag evaluations can take into account contextual information about the user, application, or action.
"fib-algo" flag returns a different result if our email ends with
Let's run the fibonacci calculator once as a customer (without being logged in).
Then login (use any email ending in
...@faas.com) and observe the impact.
This effect is driven by the rule defined in the
Feel free to experiment with your own flag values and rules!
If you used a kind cluster, you can clean everything up by running:
kind delete cluster