kustomize build: Render Overlays for Validation
kustomize build <dir> renders a kustomization into the final manifests, the output you then validate or apply in CI.
The standalone kustomize binary tracks newer features than the kubectl-embedded one. This note covers the build subcommand as the front of a validate-or-apply pipeline; the dedicated kustomize cluster covers fields and transformers in depth.
What it does
kustomize build reads a kustomization.yaml, applies its resources, patches, generators, and transformers, and prints the rendered manifests to stdout. --enable-helm allows helmCharts inflation, and --load-restrictor controls whether files outside the directory may be referenced.
Common usage
kustomize build overlays/prod
kustomize build overlays/prod | kubectl apply -f -
kustomize build --enable-helm base/
kustomize build --load-restrictor LoadRestrictionsNone ./overlayOptions
| Flag | What it does |
|---|---|
| build <dir> | Render the kustomization at <dir> |
| --enable-helm | Allow helmCharts inflation during build |
| --load-restrictor | LoadRestrictionsRootOnly (default) or None |
| -o, --output | Write to a file or directory instead of stdout |
| --enable-alpha-plugins | Permit exec/container plugins |
In CI
kustomize build is the first stage of kustomize build overlay | kubeconform -strict -, so a validator sees rendered resources rather than overlay files. Enable pipefail so a build failure fails the pipeline instead of being swallowed by the pipe. The standalone binary and kubectl kustomize can differ in version, so pin which one CI uses.
Common errors in CI
accumulating resources: ... must build at directory: not a valid directory means a resources path is wrong. security; file ... is not in or below the current directory means a ../ reference blocked by the default load restrictor; restructure or use --load-restrictor LoadRestrictionsNone knowingly. helmCharts ... must specify --enable-helm means the chart inflation flag is missing.
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