Stop 08 · Kubernetes & OrchestrationTopics · 3/12

ConfigMaps & Secrets

Part of the DevOps Roadmap

In short

You want the same image in dev and prod, just with a different database URL and log level. ConfigMaps and Secrets hold those settings outside the image, so one build runs everywhere.

ConfigMaps store non-sensitive configuration data, Secrets store sensitive values (base64-encoded, not truly encrypted by default) — both let you decouple configuration from your container images.

The mascot pins a menu card on a notice board while holding a sealed envelope in the other hand.

Think of it like this

Notice board vs sealed envelope

The hostel mess menu goes on the notice board; anyone can read it. The warden's locker code goes in a sealed envelope, handed only to who needs it. ConfigMaps are the notice board. Secrets are the envelope, but you still have to guard it.

Watch it happen

Which one should hold this value?

ConfigMap

  • LOG_LEVEL, feature flags, URLs
  • Stored as plain text
  • Fine to keep in Git

Secret

  • Passwords, API keys, TLS certs
  • Only base64-encoded by default
  • Restrict with RBAC, encrypt at rest

If leaking the value would hurt, it's a Secret, and it still needs RBAC, encryption at rest and ideally an external secrets manager.

The big ideas

What you need to know

Config outside the image

Build the image once. Inject settings per environment, so dev and prod run the exact same tested artefact.

base64 is not encryption

Anyone who can read a Secret can decode it in one command. Lock down who can get secrets with RBAC.

Env vars or files

Load values as environment variables, or mount them as files. Mounted files update without a restart, env vars don't.

External stores scale better

Many teams sync secrets from Vault or a cloud secrets manager instead of keeping them in YAML at all.

See it in code

Walk through the code

yaml
1apiVersion: v12kind: ConfigMap3metadata: { name: app-config }4data:5  LOG_LEVEL: "info"6---7apiVersion: v18kind: Pod9metadata: { name: api }10spec:11  containers:12    - name: api13      image: myapi:114      envFrom:15        - configMapRef: { name: app-config }16        - secretRef: { name: db-creds }

1/3A ConfigMap with non-sensitive settings, safe to commit alongside your manifests.

Create the Secret from the command line so it never sits in Git: kubectl create secret generic db-creds --from-literal=DB_PASSWORD=devpass

Save yourself the pain

Common mistakes

Oops

Committing a Secret YAML with base64 values to a public repo, thinking it's encrypted.

Do this instead

Treat base64 as plain text. Create secrets from the CLI, or use Sealed Secrets or External Secrets to keep Git safe.

Oops

Updating a ConfigMap and expecting env vars in running pods to change.

Do this instead

Env vars are read at start-up. Restart with kubectl rollout restart deploy/api, or mount the config as files instead.

Your mission

One image, two configs

~25 min

Quick check

What protects a Kubernetes Secret by default?

Go deeper

  1. 1Create a ConfigMap and mount it as environment variables in a Pod.
  2. 2Create a Secret and reference it in a Deployment, and note it's only base64-encoded, not encrypted.
  3. 3Learn why a real production setup often pairs Secrets with a dedicated secrets manager (Phase 12) for actual encryption.

More topics at this stop

Stuck on this topic? Ask an Insider

Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.

Download
InsideEdge