31.4 ConfigMapGenerator and SecretGenerator
Right, let’s talk about the two workhorses that will save you from a life of endless copy-pasting: ConfigMapGenerator and SecretGenerator. Forget manually crafting individual ConfigMaps and Secrets for every environment; that way lies madness and a carpal tunnel diagnosis. These generators are Kustomize’s way of saying, “Give me your raw data, some rules, and I’ll handle the boilerplate for you.” It’s configuration management, not configuration data entry.
The core idea is beautifully simple. You define a generator in your kustomization.yaml that points to a source of data—be it a file, a literal value, or even an entire .env file. When you run kustomize build (or kubectl apply -k), Kustomize reads that source, creates the appropriate Kubernetes resource manifest (ConfigMap or Secret), and injects it into your final output. The magic is that it also automatically appends a content hash to the name, which is the key to forcing rolling updates when the data changes. We’ll get to that glorious trick in a second.
Defining Generators in your kustomization.yaml
You don’t define these in your resources list. They get their own special section. You can define them under the configMapGenerator or secretGenerator keys. Here’s the basic structure:
# kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
configMapGenerator:
- name: my-app-config
files:
- config.properties
literals:
- DB_HOST=production-db.example.com
secretGenerator:
- name: my-app-secrets
files:
- secrets.properties
literals:
- API_KEY=sup3rs3cr3t
When you build this, Kustomize will create two manifests. The ConfigMap will be named something like my-app-config-8mt52t5gt9 and the Secret will be my-app-secrets-t792tbb6c5. That gibberish suffix is the hash of the contents.
The Glorious, Automatic Content Hash
This is the killer feature. In vanilla Kubernetes, if you update the data in a ConfigMap or Secret, you have to manually restart your Pods to pick up the new changes. It’s a tedious and error-prone process. Kustomize fixes this by making the resource name dependent on its content. Change a single character in your config.properties file, and the next kustomize build will generate a ConfigMap with a completely new hash suffix.
Why is this brilliant? Because your Deployment manifest references the ConfigMap by name (e.g., configMapRef: name: my-app-config-8mt52t5gt9). When the name changes, Kubernetes sees it as a brand new object to mount. For a Pod that uses this ConfigMap as an environment variable source or a volume, this change in the Pod’s spec triggers a rolling update. Your new Pods come up with the new configuration, automatically. It’s a thing of beauty.
Sourcing Data from Files, Literals, and .env Files
You’ve got options for how you feed data into these generators.
files: This is for when you have whole files you want to mount. Each key in the generated resource will be the filename, and the value will be the file’s content.literals: Perfect for one-off values. The format isKEY=VALUE. Don’t forget the equals sign; it’s a common footgun.envs: This one is weirdly powerful. You can point it to an.envfile, and it will import every key-value pair from it. Heads up: ForconfigMapGenerator, this creates keys from the file. ForsecretGenerator, it’s the intended use case and works perfectly.
configMapGenerator:
- name: app-config
files:
- server-config.yaml # Creates a key 'server-config.yaml'
literals:
- LOG_LEVEL=DEBUG
- CACHE_SIZE=100
secretGenerator:
- name: app-secrets
envs:
- .env.production # Imports all key/vals from this file as secret data
literals:
- JWT_SECRET=shhhhh
Behavior and Caveats: It’s Not All Perfect
Now, the designers made a few choices here… let’s call them “interesting.”
First, the files directive for ConfigMaps. If your sole purpose is to create a ConfigMap where a key is the filename and the value is the file’s content—great! But if you want to take the content of a file and stuff it into a specific key with a different name? You can’t do that directly here. You’d need to use a generator option to change the key, which feels a bit clunky. Sometimes, for complex structures, you’re better off generating the ConfigMap YAML yourself and just letting Kustomize handle the naming hash.
Second, the behavior field. This is crucial for managing conflicts. You can set it to create, replace, or merge. If you have two generators trying to create a ConfigMap with the same name, create will error out (good!), replace will overwrite the first with the second (powerful, dangerous), and merge will combine their data sources (often what you want if you’re being clever with bases and overlays).
configMapGenerator:
- name: important-config
behavior: merge
files:
- common-settings.yaml
literals:
- OVERRIDE_THIS=value
Best Practices: Don’t Be That Person
- Never put real secrets in your
kustomization.yaml. ThesecretGeneratorwithliteralsis for example code and quick tests. For love of all that is holy, useenvsto pull from a.envfile that is gitignored. Or better yet, use a proper secret management system like SOPS or Vault with Kustomize generators. - Embrace the hash. Don’t try to fight it by using
nameSuffixornamePrefixto override the generated name. You’ll just break the automatic update mechanism. Let the hash do its {{< bibleref “Job 3 ” >}}. Use--enable-alpha-pluginsfor advanced stuff. Want to generate secrets from AWS or GCP? There are generator plugins for that, but they require that flag because they’re still alpha. They’re incredibly useful, but know the trade-off. - Your source files are the source of truth. Since the generated manifests are ephemeral (rebuilt every time), all your changes should be made to the source files (
config.properties) or thekustomization.yamlitself, never to the generated YAML output.
So there you have it. Use these generators relentlessly. They abstract away the tedious parts, eliminate a whole class of deployment errors, and finally give you a sane way to manage configuration drift. Just watch out for those literal values—that equals sign will get you every time.