Sign in
← Kubernetes: Kustomize and Helm
6 min · easy · Lesson 5 of 9

Kustomize: ConfigMap generator

configMapGenerator builds a ConfigMap from literals and files, and the hash in its name forces the Pod to restart on a change.

ConfigMap is a Kubernetes object that stores application configuration as key-value pairs. People usually write it as a separate YAML file. Kustomize offers a second way: describe the data sources right in kustomization.yaml, and the object gets built at render time.

Why use a generator

A hand-written ConfigMap duplicates settings that already live in nearby files: nginx.conf, .env. The two copies drift apart at the first edit. On top of that, a hand-written ConfigMap lives under a fixed name, and editing its data doesn't restart the Pod. The generator solves both problems: it pulls data from the source files and appends a content hash to the object's name.

Three data sources

configMapGenerator can take data from three places.

literals - KEY=value pairs listed right in the config:

configMapGenerator:
  - name: app-config
    literals:
      - APP_COLOR=blue
      - APP_MODE=prod

files - the whole content of a file. The key becomes the file name, the value is the entire text. Handy for dropping a whole config file into a ConfigMap:

configMapGenerator:
  - name: nginx-config
    files:
      - nginx.conf
      - default.conf=configs/site.conf

The second line shows a rename: the key will be default.conf, and the content comes from configs/site.conf.

envs - a file in KEY=value format, where each line becomes its own ConfigMap key. Lines starting with # and empty lines are skipped. The difference from files matters: files puts the whole file under one key, envs parses the file line by line.

configMapGenerator:
  - name: app-env
    envs:
      - app.env

Sources combine: a single generator can have both literals and files.

SourceWhat lands in the ConfigMapWhat becomes the key
literalspairs straight from kustomization.yamlthe part of the string before =
filesthe whole file as one valuethe file name or the name before =
envseach line of the file separatelythe key from the file's line

You can see the result by rendering. For app.env with two lines DB_HOST=db and DB_PORT=5432, you'd get:

kubectl kustomize .
apiVersion: v1
data:
  DB_HOST: db
  DB_PORT: "5432"
kind: ConfigMap
metadata:
  name: app-env-4k4hb6fd6t

The hash suffix

edit APP_COLOR=green content hash new name hash suffix updates ref Deployment ref updated new revision rollout new Pods
The hash exists for exactly this chain: without a name change, the Pod template won't change.

Kustomize appends a content hash to the generated object's name: app-config-8c488fccbt. Change the value, and the hash changes, and so does the name.

This is done to restart the Pod. A Deployment references a ConfigMap by name. As long as the name stays fixed, a data edit is invisible to the Deployment: spec.template hasn't changed, so no rollout starts. A container gets its ConfigMap environment variables at startup, so running Pods keep seeing the old values until something restarts them.

With the hash suffix, it all falls into place on its own. Kustomize changes the object's name and fixes up the reference to it inside the Deployment at the same time. The Pod template changes, the cluster sees a new revision, and rolls out the update. The hash gets recalculated whenever a patch or an overlay changes the generator's data too.

Sometimes the suffix gets in the way: something outside references the ConfigMap by a fixed name, or a third-party controller reads it. Then you turn the suffix off:

generatorOptions:
  disableNameSuffixHash: true

The same generatorOptions block can also hang shared labels and annotations on every object this kustomization.yaml generates.

Kustomize only fixes up the ConfigMap reference in fields it knows about: envFrom, valueFrom.configMapKeyRef, volumes.configMap, and built-in projected volume types. A name hardcoded as a string in a command argument or an annotation stays without the suffix. A manifest applied separately from this build also references the name without the suffix. That ConfigMap doesn't exist in the cluster, and a Pod with envFrom pointing at it gets stuck in CreateContainerConfigError.

Overriding in an overlay

You can extend a generator from base in an overlay through the behavior field:

# overlays/prod/kustomization.yaml
configMapGenerator:
  - name: app-config
    behavior: merge
    literals:
      - APP_MODE=production

merge adds and overwrites keys on top of the generator from base. replace replaces the content entirely: keys from base that aren't in the overlay disappear. create (the default) creates a new object.

For merge and replace, base must have a generator with the same name, or the build fails:

error: merging from generator ... Name:"other" ... does not exist; cannot merge or replace

The opposite error happens more often: a generator with a name that already exists in base, but without behavior. Kustomize treats this as an attempt to create a second copy of the same object:

error: merging from generator ... Name:"app-config" ... exists; can not use behavior: 'unspecified', behavior must be merge or replace

What usually breaks

Old ConfigMap versions don't clean themselves up. Every edit produces a new name, and kubectl apply -k doesn't delete the previous object. Over time, kubectl get cm shows a dozen app-config-*. Clean them up through prune in your GitOps tool, or by hand.

literals is no place for passwords. The content of kustomization.yaml sits in git as plain text, and a ConfigMap by definition isn't treated as a secret.

Spaces in literals don't need quotes: - GREETING=hello world gives the value hello world. What's dangerous is characters that mean something to YAML. The line - MSG=key: value turns into a dictionary, and the build fails with cannot unmarshal object. The line - HASH=a #b silently gets cut down to a, because # opens a comment. Wrap such values in quotes entirely: - "MSG=key: value".

Checking the result before applying is, again, a job for the render. To see the hashed names and every reference to them, filter the output by the generator's name:

kubectl kustomize . | grep 'name: app-config'
  name: app-config-bmmhdm2fg6
            name: app-config-bmmhdm2fg6
          name: app-config-bmmhdm2fg6

If the output has a line with the name but no hash, a reference somewhere is one that Kustomize didn't recognize.

What you'll need for the tasks

Homework

Practice the theory on your own cluster: 1 step with a check. Set up the cluster with the Kubernetes locally track, the tasks live in the k8s-practice repository.

./run.sh start k8s-kustomize-configmap-generator     # set up the starting state
./run.sh verify k8s-kustomize-configmap-generator    # check the current step

In short

Done reading?

Mark the lesson as read to move your track progress forward.

Go through it with an AI agent

The agent explains anything unclear in plain words, gives you 2 labs for this lesson and drills you on interview questions. $49 one-time, lifetime access.

Get access for $49

Tell the agent: use MCP izi, give me lesson k8s-packaging-05-kustomize-configmap-generator