Homework
Three tasks to master _helpers.tpl, define/include, scope control, and DRY patterns in Helm charts.
Setup: Start each task with a fresh chart created via helm create. All tasks can be completed locally using helm template -- no running cluster is required, though you may optionally install to verify.
Tasks
Task 1 — Multi-Image Helper with Registry Support
Create a Helm chart for a microservice that has three containers: app, sidecar-proxy, and log-collector. Each container uses a different image.
- In
values.yaml, define each container's image withregistry,repository, andtagfields. - Write a single named template called
mychart.imageRefin_helpers.tplthat takes an image dict and produces a fully qualified reference:registry/repository:tag. Ifregistryis empty, omit it. Iftagis empty, fall back to.Chart.AppVersion. - Use the helper in
templates/deployment.yamlfor all three containers, passing the correct image dict each time using adictcall.
Self-check
- ✓ Run
helm template myrel .and confirm all three container images render correctly. - ✓ Run
helm template myrel . --set app.image.registry=ghcr.ioand verify only the app container includes the registry prefix. - ✓ Run
helm template myrel . --set app.image.tag=v3.0and verify the app usesv3.0while the others fall back toappVersion. - ✓ Run
helm lint .with zero errors.
Task 2 — Scope, the Dot, and $ in Range Loops
Create a chart that generates a ConfigMap per environment using range over a list in values, while still accessing root-level helpers inside the loop.
- In
values.yaml, define a list calledenvironmentswith three entries, each havingname(e.g.,dev,staging,prod) andlogLevelfields. - Create
templates/configmaps.yamlthat uses{{- range .Values.environments }}to produce one ConfigMap per entry. - Each ConfigMap must:
- Be named
<fullname>-<env-name>-configusing themychart.fullnamehelper (requires$since dot is rebound insiderange). - Include the standard labels via
include "mychart.labels" $. - Have data keys
ENVandLOG_LEVELpopulated from the current range item.
- Be named
Self-check
- ✓
helm template myrel .produces exactly three ConfigMaps with distinct names (e.g.,myrel-mychart-dev-config). - ✓ Each ConfigMap carries the full label set (including
app.kubernetes.io/nameandapp.kubernetes.io/instance). - ✓ Removing the
$in the include call and runninghelm templateproduces an error -- this confirms you understand scope rebinding.
Task 3 — DRY Probes and Annotations via Helpers
Build a chart with a Deployment and a CronJob that share the same health-probe configuration and annotation set.
- Write a helper
mychart.httpProbethat accepts a dict withpath,port, andinitialDelaykeys, and outputs a completehttpGetprobe block (suitable for bothlivenessProbeandreadinessProbe). - Write a helper
mychart.commonAnnotationsthat merges.Values.global.annotations(a dict) with a resource-specific annotation dict passed as an argument. Use the Sprigmergefunction. - Use both helpers in the Deployment container spec and the CronJob container spec. The Deployment should add its own annotation (
deploy-version), while the CronJob adds a different one (schedule-owner). - Pipe all helper output through
nindentat the correct indentation level -- do not use thetemplateaction.
Self-check
- ✓
helm template myrel . --set global.annotations.team=sreshowsteam: srein annotations on both the Deployment and the CronJob. - ✓ The Deployment has
deploy-versionbut notschedule-owner; the CronJob has the reverse. - ✓ Probe blocks in both resources are identical, produced by the same helper.
- ✓ Changing
values.yamlprobe settings (path or port) updates both resources -- verify with twohelm templateruns. - ✓
helm lint .reports zero errors.
Grading Rubric
| Criterion | Excellent | Satisfactory | Needs Work |
|---|---|---|---|
| Helper Design | Helpers are generic, accept dicts or scoped data, and produce clean YAML with no trailing whitespace | Helpers work but are tightly coupled to specific values paths | Helpers are missing or use template instead of include |
| Scope & Dot | Correctly uses $ inside range/with; can explain why it is needed; passes custom dicts to helpers |
Uses $ correctly but cannot explain the mechanism |
Scope errors in rendered output; labels or names missing inside loops |
| nindent Usage | All helper invocations use include piped to nindent at the correct level; YAML is valid |
Indentation mostly correct with minor cosmetic issues | Broken YAML due to incorrect indentation; uses template with attempted pipe |
| DRY Principle | No duplicated YAML blocks; every repeated fragment is extracted into a named template | Most duplication removed but one or two blocks remain inlined | Significant copy-paste between templates; helpers exist but are unused |
| Validation | helm lint passes with zero warnings; helm template output is valid Kubernetes YAML |
Lint passes but template output has minor issues (e.g., empty values) | Lint errors or template rendering failures |
Tip: When debugging helpers, use helm template . --debug to see the full rendering trace. If indentation looks wrong, double-check your nindent value -- it counts from the start of the line, not from the current cursor position. A quick way to verify: pipe template output through kubectl apply --dry-run=client -f - to catch YAML structure errors.