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
- Create a chart called
multiconfig. - Add at least three different config files to
files/(e.g.,app.yaml,logging.json,routes.conf). - Template a ConfigMap that uses
{{ range $path, $bytes := .Files.Glob "files/*" }}to load all files dynamically. - Mount the ConfigMap as a volume at
/etc/multiconfigin the Deployment. - Verify with
kubectl execthat all three files appear in the mounted directory.
Self-Check
helm template multiconfig .renders a ConfigMap with all three file contents.- Adding a fourth file to
files/and re-rendering automatically includes it — no template changes needed. kubectl exec <pod> -- ls /etc/multiconfiglists all config files.
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
- Add a
values.yamlstructure 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" - In
templates/secret.yaml, use{{- if not .Values.externalSecrets.enabled }}to render a regular Secret. - Create
templates/external-secret.yamlwith{{- if .Values.externalSecrets.enabled }}to render an ExternalSecret CRD. - The Deployment should reference the same secret name regardless of which path is taken.
Self-Check
helm template . | grep "kind:"showsSecret(not ExternalSecret) by default.helm template . --set externalSecrets.enabled=true | grep "kind:"showsExternalSecret(not Secret).- The Deployment
secretRefname is identical in both renders.
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
- 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 }} - Define a named template
myapp.configDatain_helpers.tplthat renders the data section. - Reference the same computed name in the Deployment volume definition.
- Verify that changing a value produces a ConfigMap with a different name.
Self-Check
helm template . | grep "name:.*-config-"shows the hashed name.- Rendering with
--set config.env=stagingproduces a different hash suffix. - The Deployment volume references the same hashed ConfigMap name as the ConfigMap metadata name.
Grading Criteria
| Criterion | Points | Description |
|---|---|---|
| Task 1: Glob loading | 15 | ConfigMap correctly loads all files from files/ using .Files.Glob |
| Task 1: Volume mount | 10 | Files are mounted at /etc/multiconfig and accessible from the pod |
| Task 2: Conditional logic | 15 | Chart renders Secret or ExternalSecret based on externalSecrets.enabled |
| Task 2: Consistent naming | 10 | Deployment references the same secret name in both modes |
| Task 3: Hashed naming | 15 | ConfigMap name includes a content-based hash suffix |
| Task 3: Immutability | 10 | ConfigMap has immutable: true set |
| Task 3: Deployment sync | 10 | Deployment volume references the same hashed name |
| Clean templates | 10 | helm lint passes with no warnings on all three charts |
| Documentation | 5 | Each chart has meaningful comments explaining the pattern |
| Total | 100 |
Reminder
Never commit real credentials to Git, even for homework exercises. Use obviously fake values like CHANGEME or placeholder-password.