Skip to content
intermediate Phase 10 · Helm & Package Management

Creating Helm Charts

Build custom Helm charts with templates, values, and best practices.

1h 15m
0 problems
Topic Progress 0%

Chart Anatomy

Chart Anatomy

mychart/
├── Chart.yaml        # apiVersion: v2, name, version (chart semver), appVersion
├── values.yaml       # default configuration
├── templates/        # rendered into manifests
│   ├── deployment.yaml
│   ├── _helpers.tpl  # named templates, not rendered alone
│   └── NOTES.txt     # printed after helm install
├── charts/           # packaged subchart dependencies
└── .helmignore

Helm renders every file under templates/ through Go's template engine, concatenates the output, and submits it as YAML. Files starting with _ define named templates only. Chart.yaml version tracks the chart itself; appVersion tracks the packaged application — bump them independently.

Template Syntax That Works

Template Syntax That Works

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "mychart.fullname" . }}
  labels:
    {{- toYaml .Chart.Labels | nindent 4 }}
spec:
  replicas: {{ .Values.replicaCount }}
  {{- with .Values.nodeSelector }}
  nodeSelector:
    {{- toYaml . | nindent 4 }}
  {{- end }}
  {{- if eq .Values.mode "ha" }}
  strategy: { type: Recreate }
  {{- end }}

Context is everything: . is the root data inside {{ }}; with rebinds . to the block's value (so {{ . }} inside is the list itself). Helpers in _helpers.tpl avoid duplication: {{ include "mychart.fullname" . }}, built-ins .Release.Name, .Release.Namespace, .Capabilities.APIVersions.Has, plus required "replicaCount is mandatory" .Values.x.

Pitfalls and Interview Angles

Pitfalls and Interview Angles

Indentation bugs are the number-one failure: toYaml output must go through | nindent 4 (or hand-built indentation). Off-by-two spaces yields "error converting YAML" at apply time — catch it earlier with helm template | kubeconform.

Lost context in helpers. A helper invoked without . cannot see values; always pass the context: include "x" ..

Overlong names. Deployment and Service names must match selectors and stay ≤63 chars — the standard fullname helper truncates.

Unquoted numbers. Ports like 8080 rendered as 8080 are fine, but version-like values (1.10) become floats — wrap with quote.

Interview angle: describe your validation pipeline (helm lint → helm template → schema validation → diff) and explain how with changes ..

Quiz

1. What happens to files in templates/ beginning with an underscore?

Question 1 options

2. Why pipe toYaml through nindent in most templates?

Question 2 options

3. Inside a with .Values.nodeSelector block, what does {{ . }} refer to?

Question 3 options

Flashcards

Question

_helpers.tpl

Answer

Chart-local named templates (define) used via include; underscore-prefixed files render no output themselves.

Question

nindent vs indent

Answer

nindent N = newline + N spaces before content; use with toYaml for nested blocks.

Question

required function

Answer

required "msg" .Values.x aborts rendering with a message when the value is empty.

Question

Chart version vs appVersion

Answer

version = chart packaging semver; appVersion = the application version packaged inside.

Revision Notes

Key Takeaways

  • 1. A chart renders through Go templates into plain manifests — YAML errors are template errors
  • 2. Master context (the dot), with/if/range, and include with helpers
  • 3. Gate merges with helm lint + helm template + schema validation before anything reaches a cluster

Interview Tips

  • • Explain what the dot means and how with changes it — the most common template interview question
  • • Walk your CI checks for a chart and name the failure each one catches

Cheat Sheet

Chart.yaml (version/appVersion), values.yaml, templates/ (+ _helpers.tpl, NOTES.txt). Dot = context; with rebinds it; toYaml | nindent for blocks; required for mandatory values. lint + template in CI.

Continue Learning