Kustomize’s replacements directive lets you swap out values in generated YAML across all resources, not just the ones you explicitly target.

Let’s see it in action. Imagine you have a base Kustomization with a kustomization.yaml like this:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml

configMapGenerator:
- name: app-config
  literals:
  - APP_ENV=development
  - LOG_LEVEL=info

And deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: app
        image: nginx:latest
        ports:
        - containerPort: 80
        env:
        - name: APP_ENV
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: APP_ENV
        - name: LOG_LEVEL
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: LOG_LEVEL

And service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: my-app-service
spec:
  selector:
    app: my-app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

Now, you want to change APP_ENV to production and LOG_LEVEL to debug for a production build, but you don’t want to modify the original deployment.yaml. You can add a replacements section to your kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml

configMapGenerator:
- name: app-config
  literals:
  - APP_ENV=development
  - LOG_LEVEL=info

replacements:
- sourcePath: "spec.template.spec.containers.[name=app].env.[name=APP_ENV].value"
  target:
    kind: ConfigMap
    name: app-config
    fieldPath: data.APP_ENV
- sourcePath: "spec.template.spec.containers.[name=app].env.[name=LOG_LEVEL].value"
  target:
    kind: ConfigMap
    name: app-config
    fieldPath: data.LOG_LEVEL

When you run kustomize build ., Kustomize will generate a ConfigMap with APP_ENV=production and LOG_LEVEL=debug. It achieves this by finding the source values defined within the deployment.yaml (using JSONPath-like selectors) and then applying those same values to the data.APP_ENV and data.LOG_LEVEL fields in the app-config ConfigMap. This is the core idea: Kustomize finds where a value is defined (the sourcePath) and where it should be applied (the target’s fieldPath), and makes them match.

The sourcePath uses a JSONPath-like syntax to navigate the structure of a Kubernetes object. spec.template.spec.containers.[name=app] selects the container named "app" within the deployment’s pod template. env.[name=APP_ENV] then drills down to the environment variable named "APP_ENV" within that container. The .value at the end targets the actual string value of that environment variable.

The target section specifies which resource and which field within that resource should be updated. Here, kind: ConfigMap and name: app-config point to the ConfigMap generated by configMapGenerator. fieldPath: data.APP_ENV indicates that the APP_ENV key within the data field of that ConfigMap should be updated.

This replacement mechanism is powerful because it decouples your configuration values from their definitions. You can have a base configuration and then apply overlays that modify specific values without touching the original manifests. This is especially useful for managing environments (dev, staging, prod) or feature flags.

Crucially, Kustomize doesn’t just replace values in the ConfigMap itself. It uses the sourcePath as the source of truth for the value. If you were to change APP_ENV in the deployment.yaml and have a replacement rule targeting app-config, the replacement rule would take precedence if it’s defined later in the kustomization.yaml or if it has a more specific selector. The replacements directive is designed to allow you to override values that might otherwise be generated or defined in your base resources.

The replacements directive can also be used to replace values in other fields, not just env variables or ConfigMap data. For instance, you could use it to change image tags, replica counts, or resource limits across multiple resources defined in your Kustomization. The key is understanding the sourcePath and target.fieldPath to accurately pinpoint the values you want to manipulate.

What most people miss is that the sourcePath doesn’t necessarily need to point to a value that already exists in the manifest. Kustomize will attempt to create the path if it doesn’t. However, for replacements to work as intended, the target must exist. If the target doesn’t exist (e.g., the ConfigMap wasn’t generated or the field path is incorrect), the replacement will fail.

The next thing you’ll likely encounter is needing to conditionally apply replacements based on an environment variable or a build flag, which leads you into the world of Kustomize plugins or more complex patching strategies.

Want structured learning?

Take the full Kustomize course →