Skip to content
5 min read·Lesson 7 of 10

ConfigMaps and Secrets

Learn how to inject configuration and sensitive data into Pods using ConfigMaps and Secrets, without baking credentials into container images.

Hard-coding configuration and credentials in container images is a security and operational anti-pattern. Kubernetes provides ConfigMaps and Secrets to externalise this data so images remain portable and reusable across environments.

ConfigMaps

A ConfigMap stores non-sensitive configuration data as key-value pairs.

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  APP_ENV: production
  LOG_LEVEL: info
  config.json: |
    {
      "timeout": 30,
      "retries": 3
    }
kubectl create configmap app-config --from-literal=APP_ENV=production
kubectl create configmap app-config --from-file=config.json

Consuming ConfigMaps as Environment Variables

spec:
  containers:
    - name: app
      image: my-app:v1
      envFrom:
        - configMapRef:
            name: app-config     # all keys become env vars
      env:
        - name: LOG_LEVEL
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: LOG_LEVEL     # single key

Consuming ConfigMaps as Volume Mounts (Files)

spec:
  containers:
    - name: app
      volumeMounts:
        - name: config
          mountPath: /etc/app
  volumes:
    - name: config
      configMap:
        name: app-config

The file /etc/app/config.json will contain the value of the config.json key. Files mounted from ConfigMaps are automatically updated when the ConfigMap changes (within ~60 seconds).

Secrets

A Secret stores sensitive data such as passwords, API keys, and TLS certificates. Secret values are base64-encoded — they are not encrypted by default. Anyone with access to the cluster API or etcd can decode them.

Security Warning: Enable encryption at rest for etcd and restrict Secret access with RBAC. Do not commit Secret manifests with real values to source control.
kubectl create secret generic db-secret   --from-literal=DB_PASSWORD=mysecretpassword   --from-literal=DB_USER=admin
apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
data:
  DB_PASSWORD: bXlzZWNyZXRwYXNzd29yZA==   # base64 encoded
  DB_USER: YWRtaW4=

Secret Types

TypeUse
OpaqueArbitrary user data (default)
kubernetes.io/service-account-tokenService account credentials
kubernetes.io/dockerconfigjsonPrivate container registry credentials
kubernetes.io/tlsTLS certificate and key
kubernetes.io/basic-authBasic authentication

Using Secrets

spec:
  containers:
    - name: app
      envFrom:
        - secretRef:
            name: db-secret
      volumeMounts:
        - name: creds
          mountPath: /etc/credentials
          readOnly: true
  volumes:
    - name: creds
      secret:
        secretName: db-secret

External Secret Management

For production, consider using external secret managers integrated via Kubernetes operators:

  • AWS Secrets Manager / SSM Parameter Store via AWS Secrets and Configuration Provider (ASCP)
  • HashiCorp Vault via the Vault Agent Injector or CSI Secrets Store
  • External Secrets Operator — syncs secrets from AWS, GCP, Azure, Vault into Kubernetes Secrets

Next: Namespaces and RBAC — how to organise your cluster and control who can do what.

Key Takeaways

  • ConfigMaps store non-sensitive configuration as key-value pairs, injected as env vars or files.
  • Secrets store sensitive data (passwords, tokens) — base64-encoded by default, not encrypted.
  • Enable etcd encryption at rest and restrict Secret access with RBAC in production.
  • Volume-mounted Secrets are automatically updated when the Secret changes; env vars are not.
  • Avoid committing Secrets to source control — use external secret managers in production.

Test your knowledge

Try exam-style practice questions to reinforce what you've learned.

Practice Questions →