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.
| Source | What lands in the ConfigMap | What becomes the key |
|---|---|---|
literals | pairs straight from kustomization.yaml | the part of the string before = |
files | the whole file as one value | the file name or the name before = |
envs | each line of the file separately | the 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
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
- Lab 01 (Build): replace hand-written ConfigMaps with generators from the
files
config/app.envandconfig/site.conf, and build a prod overlay that changes one key. No cluster or Docker needed. - Lab 02 (Fix): in a kind cluster, a color edit doesn't reach the Pod. Find the cause, fix it so future edits roll out on their own, and clean up the leftovers.
- Commands:
kubectl kustomize <folder>,kubectl apply -k <folder>,kubectl get cm,kubectl rollout status,kubectl exec ... -- printenv.
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
configMapGeneratorbuilds a ConfigMap fromliterals,files, orenvs, with no separate YAML file.filesputs the whole file under one key,envsparses the file line by line into separate keys.- The hash in the name changes along with the data and triggers a Pod rollout, because Kustomize also fixes up the reference in the Deployment.
generatorOptions.disableNameSuffixHash: trueturns off the suffix when something outside references the name. The cost: editing the data no longer restarts the Pod.- In an overlay, you extend the generator through
behavior: mergeorreplace. - Old ConfigMaps with a previous hash stay in the cluster until someone deletes them.
Done reading?
Mark the lesson as read to move your track progress forward.
Lesson marked as done.
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.
Tell the agent: use MCP izi, give me lesson k8s-packaging-05-kustomize-configmap-generator
Progress saved in this browser
Clear your history or open this on your phone, and the marks will be gone. Leave your email and they'll move to your account. No password needed.
Done. moved to your account. You can see your progress on any device. My progress