ConfigMaps & Secrets
Configuration without rebuilding images
ConfigMaps hold non-sensitive config; Secrets hold a named-value API for secrets that's just base64 at rest. The real security lives in mount/usage, provider-managed backends (EKS CSI, External Secrets), and RBAC.
What you will learn
- Use ConfigMaps and Secrets for env/volumes
- Explain Secrets' limits at rest and mount-time options
- Integrate provider secrets stores with static-managed sync
ConfigMap = plain key-value/image; Secret looks identical but recall/export is hardened and aimed at sensitive values. Mount volume vs env; immutable flag for drift-proof config; ExternalSecret/CSI syncs from the provider into cluster Secrets.
What is this?
ConfigMap: data/stringData, used as env (singleEnv/vars/environmentFrom), volume (keys become files), CLI flags not allowed (immutable data changed post-create only via new object). Secret types: Opaque, kubernetes.io/basic-auth, tls, dockerconfigjson. Storage: etcd base64 (not encrypted by default — enable at-rest encryption!). Mount files: keys → files; subPath; permissions mode. Updates: change secret name (immutable) → pod restart; watches and rollout. External integration: AWS Secrets Manager CSI driver, External Secrets Operator, Key Vault provider for AKS, GCP Secret Manager + secret-manager volumes.
Why do you need it?
- Config changes without rebuilding a container image = faster, safer rollouts.
- Secrets never belong in images/helm values in git; provider sync keeps them out.
- Immutable means config drift is by-design absent.
- RBAC on Secrets + encryption at rest is the baseline secret hygiene.
Mental model
Laminated recipe cards on the kitchen wall vs a locked filing cabinet
ConfigMap vs Secret
Recipes (config) are safe to post; the catering contract + supplier passwords (secrets) go in the locked cabinet, and only the chef is badged to open it.
How it works
- Create ConfigMap/Secret; mount as volume or env references.
- Image pull envFrom may warn/error on missing keys → use discrete env names.
- Volume-backed Secrets: kubelet materializes files; file-permission tuning possible.
- Provider sync controllers copy provider-managed values into a Secret on a schedule or watch.
- On rotation, the sync triggers rollout or file updated; app should re-read files or restart.
Config/Secret → pod.
Examples
Immutable config + secret volume
apiVersion: v1kind: ConfigMapmetadata: { name: app-config }immutable: truedata: LOG_LEVEL: "info" MAX_CONNS: "100"# and in the pod spec:# - name: app-config# mountPath: /etc/config (volume from ConfigMap)EOFImmutable config as files: predictable, audit-able, restart-driven, no drift.
In production
- ConfigMaps per environment with immutable false for hot knobs.
- External Secrets Operator pulls DB creds from Secrets Manager into rotated Secrets.
- TLS certs mounted from a Secret mounted read-only for the ingress controller.
Best practices
- Use Secrets for anything sensitive even if 'ConfigMap would work'. Decide policy once.
- Mark sensitive-but-shared config immutable to kill the edit-pod secret wave.
- Rotate via new Secret name + rollout, not in-place edits.
- Restrict who can view Secrets via RBAC; audit gets requests.
- Enable provider CSI sync where rotation without pod restart matters.
Common mistakes
- Shipping secrets in chart values or git — the #1 real-world leak.
- envFrom blast radius: any typo/missing key fails the pod.
- Secrets in etcd plaintext (encryption config default off) — enable at-rest.
- File-based secrets assumed fresh; the kubelet only re-reads on watch/restart.
Debugging tips
- Secret volume not updating → it's a file cache; bump by pod restart or subPath gotcha.
- envFrom rejects a key with '.' unless you use that exact syntax — check the event.
- Pod can't start: kubectl describe events usually names the missing key.
- external-sync lag → compare the provider secret version vs in-cluster; watch controller logs.
Interview checkpoint
Quick quiz
Secret values in default etcd are:
Immutable ConfigMaps require: