Kustomize Strategic-Merge Patches
A strategic-merge patch is a partial manifest that Kustomize merges into a matching resource by kind and name.
Strategic-merge is the most readable patch type: write only the fields you want to change, and Kustomize merges them using Kubernetes merge semantics.
What it does
A strategic-merge patch is a fragment of a manifest. Kustomize matches it to a resource by apiVersion, kind, and metadata.name, then merges the fragment in, respecting Kubernetes merge keys (for example, container lists merge by name). The modern way to declare them is the patches field.
Common usage
# kustomization.yaml
patches:
- path: increase-replicas.yaml
# increase-replicas.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 5patches entry fields
| Field | What it does |
|---|---|
| path | File containing the patch |
| patch | Inline patch content instead of a path |
| target | Optional selector (kind, name, labelSelector) for the patch |
| target.kind / target.name | Match resources to patch |
| options.allowNameChange | Permit the patch to change metadata.name |
In CI
Prefer the unified patches field over the deprecated patchesStrategicMerge so configs keep working on newer kustomize. A patch with no target matches by the kind and name inside the patch file itself; add an explicit target to apply one patch to many resources.
Common errors in CI
"no matches for Id <Group>_<Kind>_<name>" means the patch names a resource that the base does not produce; check kind, name, and namespace. "patchesStrategicMerge is deprecated" warns to move to patches. To delete a field, set it to null using a strategic-merge directive ($patch: delete), not by omitting it.
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