Lesson 06 Secrets & ConfigMaps
Theme:

Homework: Secrets & ConfigMaps

Three tasks to reinforce ConfigMap templating, external secrets patterns, and production config management.

Task 1 — Multi-File ConfigMap with .Files.Glob

Build a Helm chart that loads all configuration files from a files/ directory into a single ConfigMap using .Files.Glob, then mounts them as a volume in a Deployment.

Requirements

  1. Create a chart called multiconfig.
  2. Add at least three different config files to files/ (e.g., app.yaml, logging.json, routes.conf).
  3. Template a ConfigMap that uses {{ range $path, $bytes := .Files.Glob "files/*" }} to load all files dynamically.
  4. Mount the ConfigMap as a volume at /etc/multiconfig in the Deployment.
  5. Verify with kubectl exec that all three files appear in the mounted directory.

Self-Check

Task 2 — ExternalSecret Template with Conditional Fallback

Create a chart that uses an ExternalSecret when external secrets are enabled, but falls back to a regular Kubernetes Secret (from values.yaml) when they are not.

Requirements

  1. Add a values.yaml structure that includes:
    externalSecrets:
      enabled: false
      secretStoreRef:
        name: aws-secrets-manager
        kind: ClusterSecretStore
      remoteRefs:
        DB_PASSWORD:
          key: prod/myapp/db
          property: password
    
    secrets:
      DB_PASSWORD: "fallback-dev-password"
  2. In templates/secret.yaml, use {{- if not .Values.externalSecrets.enabled }} to render a regular Secret.
  3. Create templates/external-secret.yaml with {{- if .Values.externalSecrets.enabled }} to render an ExternalSecret CRD.
  4. The Deployment should reference the same secret name regardless of which path is taken.

Self-Check

Task 3 — Immutable ConfigMap with Versioned Naming

Immutable ConfigMaps cannot be updated in place — they must be deleted and recreated. Implement a versioned naming strategy that creates a new ConfigMap on each change and updates the Deployment reference automatically.

Requirements

  1. Create a ConfigMap template where the name includes a hash of the data content:
    {{- $configData := include "myapp.configData" . -}}
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: {{ include "myapp.fullname" . }}-config-{{ $configData | sha256sum | trunc 8 }}
    immutable: true
    data:
    {{ $configData | indent 2 }}
  2. Define a named template myapp.configData in _helpers.tpl that renders the data section.
  3. Reference the same computed name in the Deployment volume definition.
  4. Verify that changing a value produces a ConfigMap with a different name.

Self-Check

Grading Criteria

CriterionPointsDescription
Task 1: Glob loading15ConfigMap correctly loads all files from files/ using .Files.Glob
Task 1: Volume mount10Files are mounted at /etc/multiconfig and accessible from the pod
Task 2: Conditional logic15Chart renders Secret or ExternalSecret based on externalSecrets.enabled
Task 2: Consistent naming10Deployment references the same secret name in both modes
Task 3: Hashed naming15ConfigMap name includes a content-based hash suffix
Task 3: Immutability10ConfigMap has immutable: true set
Task 3: Deployment sync10Deployment volume references the same hashed name
Clean templates10helm lint passes with no warnings on all three charts
Documentation5Each chart has meaningful comments explaining the pattern
Total100

Reminder

Never commit real credentials to Git, even for homework exercises. Use obviously fake values like CHANGEME or placeholder-password.