0004. Phase 1 creates three kinds, not seven
Status: Accepted · Date: 2026-10-25 · Design section: 4.1, 4.2, roadmap item 1
Decided: Phase 1 scaffolds only TalosCluster, TalosMachine and TalosConfigPatch, with no controllers yet
Context
The API table lists seven kinds. Roadmap item 1 asks for "CRDs and the
kubebuilder project, Helm chart and Kustomize base, deletion protection, e2e
scaffolding", without saying which kinds, and the phase ordering puts
TalosEtcdBackup in phase 5, TalosOperation and IchorInstallation in
phase 6 and TalosStorage in phase 7.
Creating a kind costs one kubebuilder create api call and is additive, so
nothing is saved by creating all seven now. Guessing their fields is what
costs: anything published in v1alpha1 has to keep working, and a field no
code reads yet is a field whose shape nothing has tested.
Decision
Phase 1 creates the three kinds the next two phases actually work on —
TalosCluster, TalosMachine, TalosConfigPatch — with
--resource=true --controller=false, since reconcilers are phase 2.
TalosStorage, TalosEtcdBackup, TalosOperation and IchorInstallation are
created in the phase that gives them behaviour.
Within those three, phase 1 defines only the fields phases 1 to 3 need. Later
phases add their own, which is backwards compatible within v1alpha1.
Deferred for now: documents[] and defaultsRule (phase 2 and 3, see ADR
0003), disks[] / systemDiskLayout / forceRemove / upgradeHold (phase
3), cni and gitops (phase 4), upgradeStrategy (phase 6), monitoring /
components[] / integrations[] (phase 9), images (phase 10).
Three field-level decisions that the design leaves open:
versionContractis required, not defaulted. Principle 4 pins the version contract in the CR so that a machinery bump cannot change what gets applied. If the field were optional and resolved at reconcile time, a bump would do exactly that. Requiring it needs no webhook; a defaulting webhook that fills it fromtalosVersionat creation can relax this later without breaking anyone.TalosMachine.spec.nodeLabels, notlabels. The design calls itlabels; inside a spec that reads as "labels on this object", when what is meant is labels to put on the Kubernetes Node.layercannot be set tosystem. The system layer is generated by Ichor, so the enum offerscluster,role,selectorandmachineonly, and the schema rejects the rest rather than a webhook having to.
Consequences
-
Phase 1 ships a small, complete API instead of a large, speculative one, and the chart's CRD set grows one kind at a time as the phases land.
-
A kind's fields get designed next to the code that reads them, so the acceptance criteria for each phase can actually check the shape.
-
The cost is that
kubectl get crdwon't show the full catalogue until phase 7. The API table in the design doc remains the place to see where it's going. -
Update:
IchorInstallationwas created in phase 6 with ADR 0059.