ConfigMaps and Secrets

ConfigMaps and Secrets

Master the art of separation. Learn to decouple your application code from its configuration and keep your most sensitive data safe in the Kubernetes vault.

ConfigMaps and Secrets: Mastering the Separation of Concerns

A fundamental principle of "Cloud-Native" engineering is the Separation of Code and Configuration. You should never hardcode an API URL, a database password, or a feature flag into your Docker image. Why? Because if you do, you have to rebuild and redeploy your entire image just to change a single variable.

In a proper Twelve-Factor App, configuration is stored in the environment. In Kubernetes, we achieve this through ConfigMaps and Secrets.

In this lesson, we will learn how to use these two objects to manage our application settings and our most sensitive credentials. We will explore how to inject them into our FastAPI apps as environment variables or as files, and how to keep our data secure using encryption and external integrations like AWS Secrets Manager.


1. The Core Difference: ConfigMaps vs. Secrets

While they look similar in YAML, they serve two very different purposes in the ecosystem.

ConfigMaps (The Information)

ConfigMaps are designed for non-sensitive configuration data. Think of them as a "Property File" or a "JSON config" for your app.

  • Use Case: Environment name (prod vs dev), API endpoints, logging levels, or UI theme settings.
  • Limit: They have a 1MB size limit.

Secrets (The Jewels)

Secrets are for sensitive data. Kubernetes treats them differently than ConfigMaps—for example, they are stored in a "tmpfs" (RAM-only filesystem) when mounted into a pod to ensure they are never written to the server's disk.

  • Use Case: Database passwords, API keys (e.g., your OpenAI or Bedrock keys), and TLS certificates.
  • Encoding: Secrets are Base64 encoded in the YAML. This is NOT encryption; it's just a way to handle binary data in a text file.

2. Defining a ConfigMap

You can create a ConfigMap from a literal value, a file, or a whole directory. Here is the YAML for an AI agent's configuration:

apiVersion: v1
kind: ConfigMap
metadata:
  name: ai-agent-config
spec:
  data:
    LOG_LEVEL: "DEBUG"
    MODEL_TEMPERATURE: "0.7"
    MAX_TOKENS: "2048"
    API_URL: "http://inference-service.production.svc"

3. Defining a Secret

When creating a Secret YAML, you must Base64 encode your values first. echo -n "top-secret-key" | base64 -> dG9wLXNlY3JldC1rZXk=

apiVersion: v1
kind: Secret
metadata:
  name: ai-agent-secrets
type: Opaque
data:
  AWS_SECRET_KEY: dG9wLXNlY3JldC1rZXk= # Base64 encoded!
  DB_PASSWORD: bXktcGE1NXcwcmQ=    # Base64 encoded!

4. Injecting into your Application

There are two primary ways to get this data into your FastAPI or Python code.

Option A: Environment Variables (The Standard)

This is the most common method. The Kubelet reads the ConfigMap and sets it as a standard Linux environment variable inside the container.

# Inside your Pod spec
env:
- name: APP_LOG_LEVEL
  valueFrom:
    configMapKeyRef:
      name: ai-agent-config
      key: LOG_LEVEL
- name: AWS_SECRET_ACCESS_KEY
  valueFrom:
    secretKeyRef:
      name: ai-agent-secrets
      key: AWS_SECRET_KEY

Python Access:

import os
log_level = os.getenv("APP_LOG_LEVEL", "INFO")

Option B: Volumes (The "File" Method)

You can "Mount" a ConfigMap or Secret as a folder. Every key in the ConfigMap becomes a file in that folder, and the value becomes the file's content.

  • Benefit: If you update the ConfigMap, Kubernetes will update the file inside the pod automatically without a restart! (This doesn't happen with env vars).
  • Best for: Large configuration files (e.g., nginx.conf or a large JSON policy).

5. Security: Moving Beyond "Base64"

As we mentioned, Base64 is not security. If someone gets access to your YAML files or your Git repository, they have your passwords.

Best Practices for Secrets:

  1. Encryption at Rest: Ensure your Kubernetes cluster (e.g., EKS) is configured to encrypt etcd.
  2. RBAC Protection: Use strict permissions so only specific users can run kubectl get secrets.
  3. External Secrets: For enterprise-grade security, don't store secrets in K8s at all. Use tools like HashiCorp Vault or the External Secrets Operator.

The AWS Way: Secrets Manager Integration

In a professional AWS environment, you use the Secrets Store CSI Driver.

  1. You create a secret in AWS Secrets Manager.
  2. You map that secret to a "SecretProviderClass" in K8s.
  3. Your Pod "Mounts" the secret as a file. This means your passwords are never stored in your YAML files or even in the K8s etcd database.

6. Practical Example: Customizing an AI Agent with ConfigMaps

Let's say you're building a LangGraph agent. You want to adjust its behavior without redeploying.

# main.py
from fastapi import FastAPI
import os

app = FastAPI()

# These are pulled from the K8s ConfigMap
AGENT_ROLE = os.getenv("AGENT_ROLE", "Helpful Assistant")
STRICT_MODE = os.getenv("STRICT_MODE", "false").lower() == "true"

@app.get("/query")
async def query_agent(prompt: str):
    # Use config to adjust agent prompt
    system_message = f"You are a {AGENT_ROLE}."
    if STRICT_MODE:
        system_message += " Be very concise."
    # ... call LangChain ...

By changing the AGENT_ROLE in the ConfigMap and restarting the pods, you can turn a "Helpful Assistant" into a "Technical Support Expert" in seconds.


7. AI Implementation: Handling Bedrock API Keys

When using LangChain with AWS Bedrock, you often need an AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.

While you could put these in a K8s Secret, the Production-Grade way is to use IAM Roles for Service Accounts (IRSA).

  • You create an IAM Role in AWS with permissions to call Bedrock.
  • You associate that Role with a ServiceAccount in K8s.
  • You tell your pod to use that ServiceAccount. Result: Your pod gets credentials automatically through the environment, but there are NO SECRETS to manage. No Base64, no YAML files, no rotation needed.

8. Summary and Key Takeaways

  • Decouple: Never hardcode configuration.
  • ConfigMaps: For public settings.
  • Secrets: For private credentials.
  • Environment vs Volume: Use env vars for simple settings; use volumes for dynamic updates or large files.
  • Security: Leverage external provides like AWS Secrets Manager for the most sensitive production data.

In the next lesson, we will look at how we handle the "Memory" of our applications: PersistentVolumes and PersistentVolumeClaims.


9. SEO Metadata & Keywords

Focus Keywords: Kubernetes ConfigMap vs Secret tutorial, K8s mount secret as volume, environment variables from ConfigMap, base64 encoding K8s secrets, AWS Secrets Manager Kubernetes integration, Python LangChain K8s config.

Meta Description: Learn how to manage application settings and sensitive credentials in Kubernetes. Master the use of ConfigMaps and Secrets to decouple your code from your configuration, and explore enterprise security patterns for your production AI and web services.

Subscribe to our newsletter

Get the latest posts delivered right to your inbox.

Subscribe on LinkedIn