kustomize edit set image: Usage, Options & Common CI Errors
Pin a freshly built image tag into a kustomization from CI.
kustomize edit set image updates the images: block of kustomization.yaml in place, the canonical way a CI pipeline promotes an overlay to the tag it just built before applying. It edits the file, so the change can be committed back via GitOps.
What it does
kustomize edit set image NAME=NEWNAME:TAG (run inside the directory holding kustomization.yaml) writes or updates an entry in the images: transformer, which then rewrites that image across all rendered manifests. NAME is the image name as it appears in the base manifests; you can change the tag, the name, or both.
Common usage
cd overlays/prod
kustomize edit set image myreg/web=myreg/web:${GIT_SHA}
kustomize edit set image myreg/web:${GIT_SHA} # tag-only shorthand
kustomize build . | kubectl apply -f -
kubectl apply -k . # or apply directlyCommon errors in CI
The silent failure is a NAME that does not match the image in the base manifests: the images: entry is recorded but matches nothing, so the build renders the original tag and your new image never deploys - confirm with kustomize build . | grep image. "must build at directory" / no kustomization.yaml means you ran it in the wrong folder; kustomize edit operates on the kustomization.yaml in the current directory. Because it mutates the file, a CI runner that does not commit or apply the change loses it; and a dirty working tree from a prior run can leave a stale pin - start from a clean checkout.
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