# Helm — Derived Rules > Derives from `domains/kubernetes/first-principles.md`. Applies P1, P3, P6. For the Helm-vs-Kustomize decision, see the decision matrix at the end of this doc and in `kustomize.md`. ## What Helm Is (P6 Modules Compose) - Helm is a package manager for Kubernetes. A chart is a versioned package of templated manifests. `helm install` renders the templates against `values.yaml` and applies the result. - A chart encapsulates a reusable deployment (an application, a database, a full stack). It is the k8s analogue of an IaC module — see `domains/infrastructure-as-code/modules.md`. - Charts live in registries (Helm registry via OCI, or the classic chart repos) and are versioned per SemVer. ## Chart Structure (P1 Declarative Desired State, C2 Clarity) - `Chart.yaml` — metadata (name, version, appVersion, dependencies). - `values.yaml` — default inputs; the chart's public interface. - `templates/` — Go-templated manifests. `templates/_helpers.tpl` holds reusable template partials. - `values.schema.json` — optional schema for values, giving type checking on inputs. Use it for published charts. - A chart should have one logical purpose. A chart that deploys an app and a database and an ingress and an observability stack has too many jobs — split it. ## Values (P5 Version Everything, C2 Clarity) - `values.yaml` holds defaults. Override per release: `helm install --set key=value` or `helm install -f my-values.yaml`. - Pin values files in git per environment. A release is reproducible from the chart version + the values file. - Sensitive values do not belong in `values.yaml`. Inject via Secrets (see `rbac.md` P9 and `domains/security/secrets.md`). Some charts accept `existingSecret` to reference a pre-created Secret. ## Release Management (P5 Version Everything, P10 Roll Forward Roll Back) - A release is a named instantiation of a chart. `helm upgrade` applies a new chart version or new values. `helm rollback` reverts to the previous release revision. - `helm history ` lists revisions; `helm rollback ` is the rollback. The rollback must be tested like any deploy (P10). - Pin the chart version: `helm install --version 1.2.3`. Never `--version latest` in production — unversioned charts drift (same anti-pattern as unpinned IaC modules). ## Templating Discipline (P1 Declarative Desired State, C2 Clarity) - Templates render to valid manifests. The chart author's job is that the rendered output is correct k8s, not that the template is clever. - Keep `templates/` readable. Heavy logic belongs in `_helpers.tpl` or in a values structure that the template merely projects. - `helm template` renders to stdout without applying — use it to review what a release will create before installing it. ## Registries (P5 Version Everything) - OCI registries are the modern chart distribution (same registry as container images, charts as OCI artifacts). Classic chart repos are legacy. - Pull from a pinned registry reference: `oci://registry/chart:1.2.3`. The digest + tag is the version. ## Helm vs Kustomize — Decision Matrix (IDEATE-10) | Axis | Helm | Kustomize | |------|------|----------| | Mechanism | Templating (Go templates) | Overlays (base + patches) | | Reuse unit | Chart (versioned package) | Base directory (kustomization.yaml) | | Distribution | Registry (OCI, chart repo) | Git (base dir in a repo) | | Values | `values.yaml` + overrides | `kustomization.yaml` + patches | | Release mgmt | `helm` tracks releases, history, rollback | None native — apply with `kubectl apply -k` | | Learning curve | Template language to learn | YAML patching, no DSL | | Blast radius | One chart, many resources, templated | One base, many overlays, patched | | Best for | Off-the-shelf apps, packaged stacks, multi-env via values | Internal apps, patching upstream manifests, env-specific deltas | | Watch out for | Template complexity, `latest` chart drift, secrets in values | No release tracking, manual rollback, patch sprawl | - Use Helm when you distribute a reusable app or consume third-party charts. Use Kustomize when you patch existing manifests or keep env deltas in one repo. - Mixing both is fine and common: Helm for the packaged parts, Kustomize for the last-mile per-env patching. Do not fight the tool that fits the job. ## What Violates Helm Discipline | Violation | Principle | |-----------|-----------| | `helm install --version latest` in prod | P5 Version Everything | | Secrets in `values.yaml` | P9 Config and Secrets are Separate, security | | Chart with 15 subcharts doing unrelated things | P6 Modules Compose (split it) | | No `values.schema.json` on a published chart | C2 Clarity | | `helm upgrade` without reviewing `helm template` output | P1 Declarative Desired State, P4 Plan Before Apply | | Untested `helm rollback` | P10 Roll Forward Roll Back |