delivery arc VI-VIII: course briefs (GitOps, supply chain, Helm contexts) + NB2 scene prompts 09-11
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
# Course VIII - Helm: Go templates, values contexts, one chart for a fleet
|
||||
|
||||
**Series position:** third course of the delivery arc. VI taught how change travels,
|
||||
VII how images are named; this course teaches how ONE definition serves MANY clusters.
|
||||
**Safety gate:** public site - technologies only. Claims source from [[helm-charts]],
|
||||
[[yaml-manifest-style]], [[kustomize-inflate-helm]] (the ArgoCD render caveat), the
|
||||
one-value-many-enforcers post (live on the blog - cross-link it), Helm/Go public docs.
|
||||
|
||||
## Title (thesis)
|
||||
**A chart is a function. The values file is the cluster speaking.**
|
||||
|
||||
## Hook - the uncomfortable default
|
||||
The default way to run one app on five clusters is five copies of the YAML, and the
|
||||
default result is five slightly different apps - each copy drifting on its own schedule,
|
||||
each "quick fix" applied to some of them. The inversion: stop copying outputs and ship
|
||||
the FUNCTION instead. A Helm chart is a template with holes; each cluster supplies one
|
||||
small values file that fills them; the rendered manifests are build artefacts nobody
|
||||
hand-edits, ever.
|
||||
|
||||
## Move 1 - It's Go under the braces
|
||||
Helm templates are Go text/template: `{{ .Values.camera.address }}` is a pipeline
|
||||
walking a values object, `_helpers.tpl` holds named template functions (labels, names)
|
||||
every manifest calls, and `include`/`toYaml`/`default` compose them. The mental shift:
|
||||
you are not writing YAML, you are writing a program whose OUTPUT is YAML - so render
|
||||
locally (`helm template`), read the output, and lint what came out, not what went in.
|
||||
Say it like you mean it: **review the render, not just the template.**
|
||||
FIELD NOTE (amber): ArgoCD deploys charts by running `helm template` - a pure render.
|
||||
Anything that needs a live cluster or an install lifecycle (`lookup`, hooks) is silently
|
||||
dead there. A chart that works under `helm install` can behave differently under GitOps -
|
||||
render the way your deployer renders.
|
||||
|
||||
## Move 2 - Contexts: the cluster's whole voice is one small file
|
||||
The fleet pattern: the chart owns EVERYTHING structural - resources, probes, security
|
||||
contexts, policy - and each cluster owns one values file (its context): names, addresses,
|
||||
sizes, feature flags. The context is deliberately values-only; the moment a context
|
||||
carries its own manifests, there are two owners for one object and they will disagree.
|
||||
One value can feed many rendered artefacts - an address appearing in the app config, the
|
||||
network attachment and two policies renders from ONE field, so the copies cannot diverge
|
||||
(the blog post "Consistency by construction beats consistency by discipline" is this
|
||||
move, lived).
|
||||
Say it like you mean it: **the chart owns the shape; the context owns the numbers.**
|
||||
|
||||
## Move 3 - Make the template refuse
|
||||
A template that renders whatever it is given just moves the failure downstream. The
|
||||
grown-up chart carries a values.schema.json: required fields, types, enums - and a
|
||||
cluster whose context omits a required value FAILS AT RENDER TIME with a message naming
|
||||
the field, in the pipeline, before anything ships. Same discipline inside the template:
|
||||
`required "camera.address is required" .Values.camera.address` beats a silent empty
|
||||
string that becomes a policy pointed at nothing.
|
||||
FIELD NOTE: the failure you want is the render that refuses - it costs a red pipeline.
|
||||
The failure you get otherwise is enforcement aimed at an address nothing lives at,
|
||||
months later, reporting healthy the whole time.
|
||||
|
||||
## Close
|
||||
Fleet consistency is not a discipline problem, it is a construction problem. Ship one
|
||||
function, let each cluster speak one small file of facts, and make the function refuse
|
||||
to run on missing facts. Divergence stops being something you police and becomes
|
||||
something the tooling cannot express.
|
||||
|
||||
## Legend terms (DOM layer)
|
||||
chart / template / Go text-template / pipeline / _helpers.tpl / values / context /
|
||||
values.schema.json / required / render (helm template) / one source many renders
|
||||
|
||||
## Scene concept (hero + slices, the v3 mechanism)
|
||||
Exploded press-works, centre-out: an engraved PRESS PLATE (the chart - dark slab, its
|
||||
face carrying an abstract lattice of rectangular voids, the "holes" clearly empty) ->
|
||||
three small VALUES CRYSTALS (per-cluster contexts - compact faceted gems, cyan, one
|
||||
subtly larger) feeding toward it from the left -> on the right, three thin RENDERED
|
||||
SHEETS fanned apart, identical framework but each carrying a different accent pattern
|
||||
(same shape, different numbers) -> below, a GATE WEDGE (the schema - amber-white edge,
|
||||
Course III's gatekeeper silhouette re-used) with one dim REJECTED SHEET stopped at it.
|
||||
7 parts, generous void, no connectors. Slice plan: collapse draws crystals + sheets into
|
||||
the press (one machine at rest); the rejected sheet collapses BEHIND the gate, never
|
||||
past it - the visual argument for Move 3.
|
||||
Reference in New Issue
Block a user