flagd is a fully open source feature flag system released as part of the OpenFeature project. Essentially, flagd in a fully-featured feature flag evaluation storage and backend evaluation system + an API and / or gRPC endpoint to interact and retrieve flag values.
flagd comes various forms: standalone binaries for every OS, a docker image or a Kubernetes Operator.
So how does it work?
Let's start with the "standalone" version of flagd. Download the latest binary for your OS from the releases page.
Extract the binary, add the executable bit (chmod +x flagd_...
) and run the binary. You will see output like this:
% ./flagd_darwin_arm64
______ __ ________ _______ ______
/_____/\ /_/\ /_______/\ /______/\ /_____/\
\::::_\/_\:\ \ \::: _ \ \\::::__\/__\:::_ \ \
\:\/___/\\:\ \ \::(_) \ \\:\ /____/\\:\ \ \ \
\:::._\/ \:\ \____\:: __ \ \\:\\_ _\/ \:\ \ \ \
\:\ \ \:\/___/\\:.\ \ \ \\:\_\ \ \ \:\/.:| |
\_\/ \_____\/ \__\/\__\/ \_____\/ \____/_/
Flagd is a simple command line tool for fetching and presenting feature flags to services. It is designed to conform to Open Feature schema for flag definitions.
Usage:
flagd [command]
...
Create your first flag
Let's create your very first flag: a simple String
flag called basic-string
which has two possible values: foo
(which returns "bar"
) and bar
(which returns "other"
). The foo
variant is set as the defaultValue
which means "bar"
should be returned. Save the following as a JSON file:
flags.json
{
"flags": {
"basic-string": {
"state": "ENABLED",
"defaultVariant": "foo",
"variants": {
"foo": "bar",
"bar": "other"
},
"targeting": {}
}
}
}
Now restart flagd and point it to your flags.json
file:
./flagd start --uri file:flags.json
You should see:
Flag Evaluation listening at [::]:8013 {"component": "service"}
Retrieve a flag value
Open a new terminal window and request the basic-string
flag:
curl -X POST "http://localhost:8013/flagd.evaluation.v1.Service/ResolveString" \
-d '{"flagKey":"basic-string","context":{}}' -H "Content-Type: application/json"
You should see:
{
"value":"bar",
"reason":"STATIC",
"variant":"foo",
"metadata":{}
}
Update defaultValue at runtime
flagd updates flag values at runtime, without a restart.
Leave flagd running and update flags.json
so that defaultValue
is now "bar"
.
flags.json
{
"flags": {
"basic-string": {
"state": "ENABLED",
"defaultVariant": "bar",
"variants": {
"foo": "bar",
"bar": "other"
},
"targeting": {}
}
}
}
Re-execute the cURL command to retrieve the basic-string
flag and you should see the value
is now "other"
. :
curl -X POST "http://localhost:8013/flagd.evaluation.v1.Service/ResolveString" \
-d '{"flagKey":"basic-string","context":{}}' -H "Content-Type: application/json"
{
"value":"other",
"reason":"STATIC",
"variant":"bar",
"metadata":{}
}
What about Kubernetes?
flagd works on Kubernetes too:
Install cert-manager if you don't have it already
Install the OpenFeature Operator
helm repo add openfeature https://open-feature.github.io/open-feature-operator/
helm repo update
helm upgrade --install openfeature openfeature/open-feature-operator
Create the feature flag via a FeatureFlag
CRD:
kubectl apply -f - <<EOF
apiVersion: core.openfeature.dev/v1beta1
kind: FeatureFlag
metadata:
name: sample-flags
spec:
featureFlagSpec:
flags:
"basic-string":
state: "ENABLED"
variants:
"foo": "bar"
"bar": "other"
defaultVariant: "foo"
targeting: {}
EOF
Tell the operator where to find the flags by defining a FeatureFlagSource
:
kubectl apply -f - <<EOF
apiVersion: core.openfeature.dev/v1beta1
kind: FeatureFlagSource
metadata:
name: feature-flag-source
spec:
sources:
- source: default/sample-flags
provider: kubernetes
port: 8080
EOF
Finally, enable those flags for your deployment by using the openfeature.dev/enabled
and openfeature.dev/featureflagsource
annotations:
apiVersion: apps/v1
kind: Deployment
metadata:
name: your-deployment
spec:
replicas: 1
selector:
matchLabels:
app: my-busybox-curl-app
template:
metadata:
labels:
app: my-busybox-curl-app
annotations:
# here are the annotations for OpenFeature Operator
openfeature.dev/enabled: "true"
openfeature.dev/featureflagsource: "default/feature-flag-source"
spec:
containers:
- name: busybox
image: yauritux/busybox-curl:latest
ports:
- containerPort: 80
args:
- sleep
- "30000"
From within your application (ie. the above pod), the flagd endpoints are available at localhost:8080
so you can do:
// From within the pod
curl --location 'http://localhost:8080/flagd.evaluation.v1.Service/ResolveString' --header 'Content-Type: application/json' --data '{ "flagKey":"basic-string"}'
In a real application, rather than curl, you would probably use the OpenFeature SDK with the flagd provider.
That's all great, but how do I build that flag JSON?
As you've seen, flagd is very simple. Arguably the hardest part is defining the flags themselves. Guessing the JSON is no fun! Thankfully, the flagd playground provides demo code and a live testing playground which makes the JSON easy!
Top comments (0)