Kustomize replacements: Copy Values Between Fields
The replacements field reads a value from one source field and writes it into one or more target field paths.
replacements is the modern successor to vars. It copies a concrete value (an image tag, a name, a host) from a source resource into target fields you select.
What it does
Each replacement has a source (a resource selected by group/kind/name and a fieldPath) and a list of targets (resources plus the fieldPaths to overwrite). Kustomize reads the source value during build and writes it into every target path, with options like delimiter and index for string splicing.
Common usage
replacements:
- source:
kind: Deployment
name: myapp
fieldPath: spec.template.spec.containers.0.image
targets:
- select:
kind: ConfigMap
name: app-config
fieldPaths:
- data.IMAGEFields
| Field | What it does |
|---|---|
| source.kind/name | Resource to read the value from |
| source.fieldPath | Path to the source value |
| targets[].select | Which resources receive the value |
| targets[].fieldPaths | Field paths in each target to overwrite |
| targets[].options.delimiter / index | Splice into part of a string field |
| source.options.delimiter | Extract part of the source value |
In CI
Use replacements to keep a value in one place and propagate it (set the image tag on the Deployment, then mirror it into a ConfigMap an app reads). fieldPaths use dotted paths with numeric indexes for lists, like containers.0.image. Render and diff in CI so a path that drifted shows up before apply.
Common errors in CI
"unable to find field path ... in replacement source" means the source fieldPath is wrong. "nothing selected by ..." means no target matched the select block; check kind and name. A create: true is needed to add a missing target field; without it a missing target path errors. Numeric list paths must use the index (containers.0), not a name.
Using this in CI
A runner has no kubeconfig, no cached context, and no interactive auth. Every kubectl invocation in CI needs the context supplied explicitly, and most confusing CI failures here are the command running against the wrong cluster or no cluster at all.
# never rely on the ambient context on a runner
kubectl --context "$KUBE_CONTEXT" -n "$NAMESPACE" get pods
# confirm what you are actually connected to before mutating anything
kubectl config current-context
kubectl cluster-info
# fail fast instead of hanging on an unreachable API server
kubectl --request-timeout=30s get nodes