Lesson 4 · Helm fundamentals
Values & overrides
The precedence rules that make one chart serve every environment and every customer.
Your win: state the values precedence order (defaults → -f
files → --set), explain global values, and read this repo's env×org
layering — the mechanism behind Course 1's matrix.
Where values come from
A template reads .Values, but that object is merged from several
sources. The precedence, lowest to highest:1
Two rules that trip people up: with multiple -f files, the last one
wins; and merging is a deep merge for maps but lists are replaced
wholesale, not concatenated.1
Global values — the one shared namespace
A subchart can't read its parent's values — except .Values.global,
a reserved section readable by the parent and every subchart alike.2
It's how you set something once (an image tag, an environment name) and have it reach
everywhere.
- gateway
{env}-{org}-values.yaml backend/values.yaml— the sharedglobal:block (image, VPA, Hasura defaults)backend/{env}-{org}-values.yaml— cross-service, per-cellbackend/<svc>/{env}-{org}-values.yaml— the most specific, wins
backend/bob/local-manabie-values.yaml
(:42-45) only needs to hold the deltas for that cell —
trimmed cpu/memory, a metrics toggle — because everything else comes from the layers below.
Same chart, ~30 cells, tiny per-cell files. That's the env×org matrix from Course 1, in Helm.
setValueTemplates
(skaffold.backend.yaml:27-31):
global.environment: "{{.ENV}}" and global.vendor: "{{.ORG}}"
(plus the image tag). Those are --set-style overrides — highest precedence — and
the templates read them back through helpers util.environment /
util.vendor (libs/util/templates/_env.tpl:6-16,37-47),
which fall back from .Values.global.environment to .Values.environment.
That's the exact wiring that turns "ENV=local ORG=manabie" into the right config everywhere.
helm -f … -f … here — Skaffold's valuesFiles: list
is that ordered set of -f flags. Reordering the list changes who wins.
Same Helm rule, expressed in the Skaffold release config.
Helm docs — Values Files + Subcharts & Global Values
Where values come from, the precedence/merge rules, and how global works.
→ helm.sh — Values Files
→ helm.sh — Subcharts & Global Values
Check yourself (from memory)
Q1. Which wins when the same key is set several ways?
-f files (last
wins) → --set. More specific overrides more general.
Q2. Which values can a subchart read from its parent?
global is the one shared section; otherwise a
subchart can't see the parent's values.
Q3. This repo's per-cell {env}-{org}-values.yaml files are small because…
-f files (LAST wins) → --set (wins all). Maps DEEP-MERGE; lists are
REPLACED wholesale. GLOBAL: .Values.global is the one section shared into
subcharts (set once, read everywhere). REPO: four layered values files per release (Skaffold
valuesFiles, last wins): gateway {env}-{org} → backend/values.yaml
(shared global) → backend/{env}-{org} → backend/<svc>/{env}-{org}
(most specific). Per-cell files hold only DELTAS. env/org injected via
setValueTemplates (global.environment/vendor), read via
util.environment/util.vendor — Course 1's env×org matrix in Helm.libs/util
chart, hooks, and how Skaffold drives releases.