kubeconform: Validate kustomize Build Output
kustomize build overlay | kubeconform - validates the fully rendered manifests, since kubeconform should see the output, not the kustomization files.
Validating raw overlays fails because a kustomization.yaml is not a Kubernetes resource. Render first with kustomize build, then pipe the result into kubeconform reading from stdin.
What it does
kubeconform reads manifests from stdin when given - as the file argument. Piping kustomize build <overlay> into it validates the actual resources that would be applied, after patches, generators, and transformers have run.
Common usage
kustomize build overlays/prod | kubeconform -strict -summary -
# or with kubectl's built-in kustomize
kubectl kustomize overlays/prod | kubeconform -strict -Options
| Piece | What it does |
|---|---|
| kustomize build <dir> | Render the overlay to plain manifests |
| kubeconform - | Read manifests from stdin |
| -strict | Catch unknown fields in the rendered output |
| -summary | Print counts after validating the stream |
In CI
Run this per overlay (dev, staging, prod) so each environment is validated as rendered. If the pipe swallows kustomize errors, split the steps: write kustomize build to a file, check its exit code, then validate the file.
Common errors in CI
A green kubeconform after a failed kustomize build is the classic trap: the pipe hides kustomize exit code 1, and kubeconform validates empty input as success. Set set -o pipefail (bash) so the pipeline fails. error while parsing: yaml: ... on stdin means kustomize emitted a warning to stdout; redirect kustomize stderr separately.
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