Applications need configuration—database URLs, feature flags, API keys. Kubernetes provides ConfigMaps and Secrets to manage configuration separately from container images. This is a core concept tested on KCNA.
Pause and predict: The 12-Factor App methodology says “store config in the environment.” If you bake a database password into your container image, what problems does that create when you need to deploy the same application to dev, staging, and production environments?
Exercise: Injecting Environment Variables
You have a ConfigMap named backend-config with a key LOG_LEVEL. Complete this partial Pod definition to inject that value as an environment variable named APP_LOG_LEVEL.
apiVersion: v1
kind: Pod
metadata:
name: backend-pod
spec:
containers:
- name: app
image: my-app:v1
# ADD YOUR CODE HERE
Solution
env:
- name: APP_LOG_LEVEL
valueFrom:
configMapKeyRef:
name: backend-config
key: LOG_LEVEL
By explicitly using valueFrom and configMapKeyRef, you map a specific key from your ConfigMap to a specific environment variable name inside the container.
Exercise: Mounting a Secret Volume
Your application needs access to a TLS certificate stored in a Secret named tls-certs. Update this Deployment to mount the secret as a volume at /etc/tls and ensure it’s read-only.
apiVersion: apps/v1
kind: Deployment
metadata:
name: secure-app
spec:
template:
spec:
containers:
- name: app
image: secure-app:v2
# ADD VOLUME MOUNTS HERE
# ADD VOLUMES HERE
Solution
volumeMounts:
- name: cert-volume
mountPath: /etc/tls
readOnly: true
volumes:
- name: cert-volume
secret:
secretName: tls-certs
Providing certificates as a read-only volume mount is the standard pattern because applications expect certificates to exist as files on the filesystem, and readOnly: true prevents accidental modification.
Exercise: Choose Your Configuration Object
For each of the following data types, decide whether you should use a ConfigMap or a Secret, and explain why.
A feature flag enabling a new UI layout (ENABLE_NEW_UI=true)
A third-party payment gateway API token
An NGINX configuration file (nginx.conf)
A private SSH key for accessing a Git repository
Solution
ConfigMap: Feature flags are not sensitive. If exposed, they don’t pose a security risk.
Secret: API tokens provide access to external systems and represent financial risk. They must be protected using RBAC and encryption at rest.
ConfigMap: Configuration files define application behavior but typically don’t contain credentials. They are meant to be visible and editable.
Secret: SSH keys grant access to external resources. Exposing them could compromise your infrastructure or codebase.
Stop and think: Secrets in Kubernetes are base64 encoded, not encrypted. If someone has access to run kubectl get secret db-creds -o yaml, they can decode the password instantly. What additional security measures would you need for real production secret management?
A developer stores an API key in a ConfigMap because “it’s just a string.” During a security audit, the API key is found in plain text in kubectl output and etcd. What should they have done differently, and why does the distinction between ConfigMap and Secret matter even though Secrets are also not encrypted by default?
Answer
The API key should be stored in a Secret, not a ConfigMap. While Secrets are only base64 encoded by default (not truly encrypted), they receive additional protections: RBAC can be configured to restrict Secret access separately from ConfigMaps, Secrets can be encrypted at rest in etcd when encryption is enabled, and Secret data is not displayed in `kubectl describe` output. ConfigMaps are designed for non-sensitive data and have none of these protections. For production, enable encryption at rest for Secrets in etcd and consider external secret management tools.
Your application reads its database URL from an environment variable injected via a ConfigMap. You update the ConfigMap to point to a new database, but the application still connects to the old one. What is happening, and how would you fix it?
Answer
Environment variables are set when the Pod starts and do not update when the underlying ConfigMap changes. The Pod must be restarted for the new value to take effect. To avoid this, mount the ConfigMap as a volume instead. Volume-mounted ConfigMaps automatically update when the ConfigMap changes (with a delay of up to a minute). The application would then read the configuration from a file rather than an environment variable, and could watch for file changes to reload without a restart.
A new hire asks: “Why not just put the database password directly in the Deployment YAML as an environment variable value?” What are the problems with this approach compared to using a Secret?
Answer
Hardcoding secrets in YAML means: the password is visible in version control (Git) to anyone with repository access, the same password is baked into the Deployment definition making it impossible to use different credentials per environment without duplicating the YAML, changing the password requires editing and redeploying the Deployment, and the plain text password appears in `kubectl get deployment -o yaml` output. Using a Secret separates the credential from the workload definition, allows different Secrets per namespace (dev/staging/prod), enables RBAC control over who can read Secrets, and keeps sensitive values out of Git.
Your team runs 500 Pods that all reference the same ConfigMap. Every time someone updates the ConfigMap, all 500 Pods detect the change and the API server experiences a load spike. What Kubernetes feature would solve this problem?
Answer
Mark the ConfigMap as `immutable: true`. Immutable ConfigMaps cannot be modified after creation, which means Kubernetes does not need to maintain watches for changes on them, significantly reducing API server load. When you need to update the configuration, create a new ConfigMap with a different name (e.g., `app-config-v2`), update the Pod specs to reference it, and delete the old one. This also protects against accidental configuration changes that could affect all 500 Pods simultaneously.
You deploy the same application to dev, staging, and production. Each environment needs a different database host and different replica count, but the container image is identical. How do ConfigMaps enable this pattern, and how does it relate to the 12-Factor App methodology?
Answer
Create a separate ConfigMap in each namespace (dev, staging, prod) with the appropriate database host value. The Deployment references the ConfigMap by name, which resolves to the namespace-local ConfigMap. The same container image runs everywhere -- only the injected configuration differs. This implements 12-Factor App principle #3 ("Store config in the environment") by strictly separating configuration from code. The build artifact (container image) is immutable and environment-agnostic, while ConfigMaps provide environment-specific settings at deploy time.