Skip to content

Helmfile

Core · prereq 04 (Kubernetes & Helm) · ~1 day

A single helm install manages one chart. A real deployment is rarely one chart — it's an ingress controller, a couple of internal services, and their supporting resources, each needing its own values and a predictable apply order. Run them by hand and you're re-typing flags and hoping you remembered the order right. Helmfile turns that fleet of releases into one declarative file: preview every change with a diff before it touches the cluster, then apply it as many times as you want and trust that a no-op stays a no-op.

TL;DR — in 30 seconds:

  • Helmfile turns a fleet of helm install calls into one declarative file — diff previews every change before it touches the cluster, and apply is idempotent: a second run reports no changes.
  • environments: layers config per stage (values: is a list, later entries win); secrets: is a second, SOPS-decrypted list layered the same way — never a plaintext substitute.
  • needs: builds a dependency graph, not a fixed top-to-bottom order — releases with no needs: relationship to each other can run at the same time, bounded by --concurrency.

Learning objectives

By the end, the junior can:

  • Declare a stack of releases in one helmfile.yaml.
  • Run the diff → apply workflow and explain why apply is idempotent.
  • Use environments to vary config per stage.

Do it with Claude

Pair, Do and Prove run in Claude Code, with the onboarding-tutor skill. Click a button to copy the exact prompt, then paste it into Claude Code in this repo.

1. Learn · acquire the concept

Read: the helmfile coursefocus §4 (minimum viable helmfile.yaml), §5 (repositories), §6 (releases), §7 (values), §8 (environments), §14 (everyday workflow). Skip for now: §10 (SOPS secrets), §12 (selectors/needs) — revisit when you hit them. Glossary (beat 5): the module’s Anki deck Read next: Helmfile documentation (official docs — full CLI reference and the helmfile.yaml schema).

Check yourself — you set ingressReplicaCount: 4 in environments/prod.yaml, redeploy, and nothing changes on the cluster. Why?

Environment values only become useful once a templated release values file reads .Environment.Values.ingressReplicaCount and assigns it to a field the chart actually understands — setting the environment value alone does nothing until something consumes it.

Check yourself — what does SOPS actually encrypt in a secrets: file?

Only the leaf values, not the keys or YAML structure — a git diff on an encrypted file still shows which key changed, even though it can't show the new value.

2. Pair · passive → active

Drive the onboarding-tutor skill:

  • "Why Helmfile instead of running helm install three times?"
  • "3-line mental model of helmfile diff vs helmfile apply."
  • "Quiz me on release vs values vs environment."

Common gotchas

  • Treating values: and environments.<name>.values as the same tree. Fix: they're two separate value systems — environment values only reach a chart once a templated *.gotmpl values file reads .Environment.Values and assigns it to a field the chart understands.
  • Assuming helmfile.yaml's release order is the actual apply order. Fix: order is decided by needs:, not by the order releases are written — releases with no dependency relationship to each other can run concurrently regardless of file position.
  • Forgetting --suppress-secrets in CI. Fix: helmfile diff prints rendered values, including any decrypted secret, straight into the log unless you pass it — never let that hit a CI log that isn't private.
Check yourself — cert-manager and external-dns both needs: [ingress-nginx] and not each other. Can they finish in a different order on different runs?

Yes — since neither depends on the other, Helmfile has no ordering guarantee between them and may run them concurrently. Only needs: relationships constrain order, never file position.

Check yourself — why is --suppress-secrets required on helmfile diff in CI?

Diff prints rendered values, which include any decrypted secret in plaintext unless suppressed — an easy way to leak a password straight into a build log.

Done when: you can explain what Helmfile adds over plain Helm, unprompted.

3. Do · produce an artifact

Exercise — declare and deploy a two-chart stack:

  1. Install Helmfile first (course §3): brew install helmfile — it needs helm + kubectl (module 04 (Kubernetes)) and a running cluster.
  2. Write a helmfile.yaml with two releases (e.g. an ingress controller + a demo app) from real repos.
  3. Add a dev environment with an environment-specific value.
  4. helmfile diff (preview), then helmfile apply.
  5. Run helmfile apply again and show the second run is a no-op (all "no diff").

Done when: both releases are deployed and a second apply reports no changes.

4. Prove · understanding gate

Mandatory. Pass bar in the Socratic gate.

  1. Walkthrough: Explain your helmfile.yaml — each release, where values come from, what the environment overrides.
  2. Alternative: Environment values vs per-release values — when each? What would you put in SOPS instead of plain text?
  3. Failure & debug: helmfile apply fails on release 2 only. What state is release 1 in, and how do you recover?
  4. Provenance: Which parts did the agent generate, and how did you verify the second apply was truly idempotent?

Pass bar: you can defend the stack definition and the diff-then-apply loop. "It applied" without understanding idempotency = back to Pair.

5. Retain · fight forgetting

Study the module deck SE Onboarding::06 Helmfile — its 13 theme subdecks let you drill one area at a time. It syncs to your Anki automatically on pull (anki-sync).

Done when: you can recall — from the deck — helmfile.yaml, release, environment, diff/apply, and repositories.

Key takeaways

  • Helmfile turns a fleet of helm install calls into one declarative file. diff previews every change before it touches the cluster; apply is idempotent — a second run reports no changes.
  • environments: layers config per stage, not per release. values: is a list where later entries win, but an environment value only reaches a chart once a templated *.gotmpl values file reads .Environment.Values and assigns it to a field the chart actually understands.
  • secrets: is a second, SOPS-decrypted list layered the same way as values: — never a plaintext substitute, and SOPS only encrypts leaf values, so a git diff still shows which key changed.
  • needs: builds a dependency graph, not a fixed top-to-bottom order. Releases with no needs: relationship to each other can run concurrently, bounded by --concurrency — file position never decides apply order.
  • --suppress-secrets is mandatory in CI. helmfile diff prints rendered values, including any decrypted secret in plaintext, straight into the log unless you pass it.

Go deeper — curated resources

Hand-picked external material to take this topic further — the best books, courses, talks, and writing. Cost is tagged Free, Free online (full text/course free on the web), or Paid.

  • Repo · Helmfile — Official. The tool itself — README, docs, and source. Free.
  • Docs · Helm — Official. The layer Helmfile orchestrates declaratively. Free.
  • Blog · Tools to Manage Your Helm Releases Declaratively — Official Helm blog. Where Helmfile fits among the declarative release-management tools. Free.

Gate log (mentor fills on pass)

  • Date passed: / Passed by: / checked by: / Weak spots: