Environment overrides
Run the same kdef project against staging, production, and anything else, without duplicating files.
You have one deployment. It needs to run in staging with 1 replica, in production with 5 replicas and a different image tag. With Kustomize you'd build an overlays/ tree. With kdef you write one override file per environment.
The pattern
k8s/
├── vars.kdef
├── images.kdef
├── api.kdef
└── environments/
├── staging.kdef
└── production.kdef
environments/production.kdef
use_vars {
environment = "production"
image_tag = "v2.4.1"
}
override "app" "api" {
scale {
replicas = 5
}
}
environments/staging.kdef
use_vars {
environment = "staging"
image_tag = "staging-latest"
}
override "app" "api" {
scale {
replicas = 1
}
}
Render and deploy
# Default (no env flag): uses vars.kdef defaults
kdef render --dir k8s/
# Staging
kdef render --dir k8s/ --env staging
kdef diff --dir k8s/ --env staging
kdef apply --dir k8s/ --env staging
# Production
kdef render --dir k8s/ --env production
kdef apply --dir k8s/ --env production
What goes where
| Belongs in | Example |
|---|---|
vars.kdef |
Variable declarations with defaults. Ingress defaults. Imports. |
environments/*.kdef |
Per-environment variable values (use_vars) and per-deployment override blocks. |
values/<env>.json |
Complex values: lists, maps, multi-line strings. Load with --values. |
| CLI flags | One-off overrides: --set image_tag=v1.2.3. |
Precedence, highest wins:
--set/--valuesCLI flagsuse_varsin the loadedenvironments/<env>.kdef- Per-deployment
env/setinroot.kdef - Global
env/setinroot.kdef defaulton thevariabledeclaration
override blocks
override "app" "<name>" targets a deployment (or statefulset) by name. As of kdef v0.7.5 an override changes the replica count only:
override "app" "api" {
scale {
replicas = 5
}
}
Containers, env vars and other nested blocks can't be overridden this way; an override file that contains them fails to parse. Make the value a variable in the base file instead and set it per environment.
Tips
- Keep
environments/*.kdefsmall. If it's getting long, your base file is probably missing an abstraction: pull the shared parts up. - CI pipelines usually pass
--envfrom the branch name or a pipeline parameter:kdef apply --dir k8s/ --env "$DEPLOY_ENV". - Combine with GitOps: commit
environments/production.kdef, let Flux/ArgoCD apply it on merge to main. See GitOps → Flux.