Kustomize
Kubernetes
configuration management
DevOps
YAML

Replace contents of an item in a list using Kustomize

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Kustomize modifies Kubernetes YAML without templates by applying patches to base configurations. Replacing items in a list (like containers, volumes, or env vars) is one of the trickiest operations because YAML lists do not have keys — Kustomize uses Strategic Merge Patches that match list items by a merge key (usually name). For lists without merge keys, you need JSON 6902 patches that target items by array index.

Strategic Merge Patch (Match by Name)

Kubernetes strategic merge patches match list items by their merge key. For containers, the merge key is name:

yaml
1# base/deployment.yaml
2apiVersion: apps/v1
3kind: Deployment
4metadata:
5  name: my-app
6spec:
7  template:
8    spec:
9      containers:
10        - name: app
11          image: myapp:1.0
12          resources:
13            limits:
14              memory: "128Mi"
15              cpu: "250m"
yaml
1# overlays/production/patch.yaml
2apiVersion: apps/v1
3kind: Deployment
4metadata:
5  name: my-app
6spec:
7  template:
8    spec:
9      containers:
10        - name: app  # Matches by name
11          image: myapp:2.0  # Replaced
12          resources:
13            limits:
14              memory: "512Mi"  # Replaced
15              cpu: "1000m"  # Replaced
yaml
1# overlays/production/kustomization.yaml
2apiVersion: kustomize.config.k8s.io/v1beta1
3kind: Kustomization
4resources:
5  - ../../base
6patchesStrategicMerge:
7  - patch.yaml
bash
kustomize build overlays/production
# Result: container "app" has image myapp:2.0 and updated resources

JSON 6902 Patch (Match by Index)

For precise control or when items have no merge key, use JSON 6902 patches:

yaml
1# overlays/production/kustomization.yaml
2apiVersion: kustomize.config.k8s.io/v1beta1
3kind: Kustomization
4resources:
5  - ../../base
6patches:
7  - target:
8      kind: Deployment
9      name: my-app
10    path: patch.yaml
yaml
1# overlays/production/patch.yaml
2# Replace the entire first container
3- op: replace
4  path: /spec/template/spec/containers/0
5  value:
6    name: app
7    image: myapp:2.0
8    resources:
9      limits:
10        memory: "512Mi"
11        cpu: "1000m"
12
13# Replace just the image of the first container
14- op: replace
15  path: /spec/template/spec/containers/0/image
16  value: myapp:2.0
17
18# Replace a specific env var (third item in env list)
19- op: replace
20  path: /spec/template/spec/containers/0/env/2/value
21  value: "new-value"

Adding Items to a List

yaml
1# JSON 6902 — add a new container to the list
2- op: add
3  path: /spec/template/spec/containers/-
4  value:
5    name: sidecar
6    image: sidecar:latest
7    ports:
8      - containerPort: 9090
9
10# Add a new env var to the first container
11- op: add
12  path: /spec/template/spec/containers/0/env/-
13  value:
14    name: NEW_VAR
15    value: "hello"

The - at the end of the path means "append to the array."

Removing Items from a List

yaml
1# Remove the second container (index 1)
2- op: remove
3  path: /spec/template/spec/containers/1
4
5# Remove a specific env var by index
6- op: remove
7  path: /spec/template/spec/containers/0/env/0

Replacing Environment Variables

Environment variables are a common list replacement scenario:

yaml
1# base/deployment.yaml
2spec:
3  template:
4    spec:
5      containers:
6        - name: app
7          image: myapp:1.0
8          env:
9            - name: DATABASE_URL
10              value: "postgres://localhost:5432/dev"
11            - name: LOG_LEVEL
12              value: "debug"
13            - name: API_KEY
14              valueFrom:
15                secretKeyRef:
16                  name: app-secrets
17                  key: api-key
yaml
1# Strategic merge patch — matches env items by name
2apiVersion: apps/v1
3kind: Deployment
4metadata:
5  name: my-app
6spec:
7  template:
8    spec:
9      containers:
10        - name: app
11          env:
12            - name: DATABASE_URL
13              value: "postgres://prod-db:5432/production"
14            - name: LOG_LEVEL
15              value: "warn"

Inline Patches

For small changes, define patches inline in kustomization.yaml:

yaml
1apiVersion: kustomize.config.k8s.io/v1beta1
2kind: Kustomization
3resources:
4  - ../../base
5patches:
6  - target:
7      kind: Deployment
8      name: my-app
9    patch: |-
10      - op: replace
11        path: /spec/template/spec/containers/0/image
12        value: myapp:2.0
13      - op: replace
14        path: /spec/replicas
15        value: 3

Using replacements (Kustomize 4.5+)

The replacements field provides a declarative way to copy values between resources:

yaml
1apiVersion: kustomize.config.k8s.io/v1beta1
2kind: Kustomization
3resources:
4  - ../../base
5replacements:
6  - source:
7      kind: ConfigMap
8      name: app-config
9      fieldPath: data.image_tag
10    targets:
11      - select:
12          kind: Deployment
13          name: my-app
14        fieldPaths:
15          - spec.template.spec.containers.[name=app].image

Common Pitfalls

  • Strategic merge patch replacing the entire list: If you include a list in a strategic merge patch but omit existing items, those items are not deleted — they remain because the merge matches by the name key. However, if you use a plain merge patch (not strategic), the entire list is replaced.
  • Wrong array index in JSON 6902: Array indices are zero-based. Targeting /containers/1 when there is only one container results in path not found. Verify the base manifest's list length before patching by index.
  • Merge key mismatch: Strategic merge patches match containers by name, volumes by name, ports by containerPort. If the name in your patch does not match any item in the base, a new item is added instead of replacing the existing one.
  • Patching items with no merge key: Some lists (like args, command) have no merge key. Strategic merge patches replace the entire list in these cases. Use JSON 6902 patches for precise item-level control.
  • Order of patch application: Kustomize applies patches in the order listed in kustomization.yaml. Later patches see the result of earlier ones. If two patches modify the same list item, the second patch operates on the already-modified version.

Summary

  • Use strategic merge patches to replace list items by their merge key (usually name)
  • Use JSON 6902 patches (op: replace, op: add, op: remove) for index-based or precise list modifications
  • The - path suffix appends to an array; numeric indices target specific positions
  • Environment variables and containers use name as the merge key for strategic merge patches
  • Verify base manifest structure with kustomize build before writing patches to ensure correct paths

Course illustration
Course illustration

All Rights Reserved.