Homework
Design and implement a production-grade multi-environment deployment pipeline with encrypted secrets.
Task 1 — Production-Grade Directory Structure and Values Layering
Design a multi-environment Helm deployment for a web application with the following requirements:
- Three environments: dev, staging, and prod
- Two regions for production: us-east and eu-west
- A base values file shared across all environments
- Region-specific values files that layer on top of the environment file
Your directory structure must follow the layered pattern:
deploy/
charts/
webapp/ # your Helm chart
values/
base.yaml # shared defaults
envs/
dev.yaml
staging.yaml
prod.yaml
regions/
us-east.yaml
eu-west.yaml
The values files must differ across environments and regions on at least these dimensions:
| Value | Dev | Staging | Prod (us-east) | Prod (eu-west) |
|---|---|---|---|---|
| Replicas | 1 | 2 | 5 | 3 |
| Image tag | latest | v2.0.0-rc1 | v2.0.0 | |
| Ingress host | dev.local | staging.example.com | us.example.com | eu.example.com |
| Log level | debug | info | warn | |
| CPU request | 50m | 200m | 500m | 500m |
Demonstrate the layering by rendering each variant and verifying the merge order:
# Dev (base + dev)
helm template webapp deploy/charts/webapp \
-f deploy/values/base.yaml \
-f deploy/values/envs/dev.yaml
# Prod US-East (base + prod + us-east)
helm template webapp deploy/charts/webapp \
-f deploy/values/base.yaml \
-f deploy/values/envs/prod.yaml \
-f deploy/values/regions/us-east.yaml
# Prod EU-West (base + prod + eu-west)
helm template webapp deploy/charts/webapp \
-f deploy/values/base.yaml \
-f deploy/values/envs/prod.yaml \
-f deploy/values/regions/eu-west.yaml
Self-check
- Directory follows the layered pattern with separate
envs/andregions/directories - Dev renders with 1 replica,
latesttag,debuglog level - Prod US-East renders with 5 replicas,
v2.0.0tag,us.example.comingress,warnlog level - Prod EU-West renders with 3 replicas,
v2.0.0tag,eu.example.comingress - Region files override only the region-specific values (replicas, ingress host) without repeating everything from the env file
helm lintpasses for all variants
Task 2 — Helmfile with Encrypted Secrets
Build a complete Helmfile configuration that manages all environments from Task 1, including encrypted secrets. Your helmfile.yaml must:
- Define
dev,staging,prod-us-east, andprod-eu-westas named environments - Compose the correct values file layers for each environment (base + env + optional region)
- Include a SOPS-encrypted secrets file per environment under
deploy/values/secrets/ - Use the
secrets:field in Helmfile releases for automatic decryption
Your secrets files must contain at least:
secrets.dbPassword— different per environmentsecrets.apiKey— different per environmentsecrets.tlsCert— present only in staging and production
Example Helmfile structure:
# helmfile.yaml
environments:
dev:
values:
- namespace: dev
staging:
values:
- namespace: staging
prod-us-east:
values:
- namespace: prod
- region: us-east
prod-eu-west:
values:
- namespace: prod
- region: eu-west
---
releases:
- name: webapp-{{ .Environment.Name }}
chart: deploy/charts/webapp
namespace: {{ .Values.namespace }}
createNamespace: true
values:
- deploy/values/base.yaml
- deploy/values/envs/{{ ... }}.yaml # your logic here
{{- if .Values.region }}
- deploy/values/regions/{{ .Values.region }}.yaml
{{- end }}
secrets:
- deploy/values/secrets/{{ .Environment.Name }}.yaml
Demonstrate all of the following commands:
# Preview what each environment will deploy
helmfile -e dev template
helmfile -e prod-us-east template
# Show the diff before applying
helmfile -e staging diff
# Deploy
helmfile -e dev apply
# List managed releases
helmfile -e dev list
# Clean up
helmfile -e dev destroy
Self-check
- Helmfile defines all four environments with correct values composition
helmfile -e dev templaterenders with dev values and decrypted dev secretshelmfile -e prod-us-east templateincludes base + prod + us-east region + prod-us-east secrets- Encrypted secrets files are committed to Git (plaintext keys, encrypted values)
- The
key.txt(age private key) is listed in.gitignore helmfile -e dev applydeploys successfully to the cluster- Kubernetes Secrets contain the correct decrypted values
Task 3 — CI Pipeline Design
Write a GitHub Actions workflow (or equivalent CI configuration) that implements the following multi-environment deployment pipeline:
- On push to any branch: run
helmfile -e dev templateandhelm lintfor all environments to validate the chart - On merge to main: automatically deploy to staging with
helmfile -e staging apply - On Git tag (v*): deploy to both production regions with manual approval gates
The workflow must handle secrets correctly:
- The age private key is stored as a GitHub Actions secret (
SOPS_AGE_KEY) - The workflow writes the key to a temporary file and sets
SOPS_AGE_KEY_FILE - The key file is cleaned up after deployment
Provide the complete .github/workflows/deploy.yaml file and explain each step in inline comments.
Self-check
- Workflow has three distinct triggers: push, merge to main, and tag creation
- Validation runs on every push without deploying
- Staging deployment is automatic on merge to main
- Production deployment requires manual approval (uses
environmentwith protection rules) - Both production regions are deployed (sequentially or in parallel)
- The age key is injected from GitHub Secrets and cleaned up after use
- The workflow installs Helm, Helmfile, helm-diff, helm-secrets, and SOPS
Grading Rubric
| Criterion | Points | Requirements |
|---|---|---|
| Task 1 — Directory structure and layering | 30 | Layered pattern with envs/ and regions/; all 5 variants render correctly; region files are minimal overlays; helm lint passes for all |
| Task 2 — Helmfile with encrypted secrets | 40 | Four environments defined; correct values composition per environment; SOPS encryption working; helmfile apply deploys successfully; secrets verified in cluster |
| Task 3 — CI pipeline design | 20 | Three triggers; validation on push; auto-deploy staging; manual approval for prod; correct secret handling; cleanup step |
| Code quality and documentation | 10 | Clean YAML formatting; meaningful comments in Helmfile and workflow; .gitignore excludes private keys; clear README or inline explanation |