The operator ruled the implementation repo's main (50c8719) the latest and accepted state. Sync the spec to it. Accepted changes are reflected: one bare-metal environment, TrueNAS bulk storage, R2 off-cluster backup, CloudNativePG, single-node VPN gateway with Cilium fail-closed, inbound WireGuard, per-app auth sidecars, Renovate, the CI gate as approver, and the pm-agent. New ADR-0017..0025; ADR-0016 corrected and accepted; R-* IDs unchanged, eight amended. Where the implementation has simply not met a requirement, the requirement stands and the shortfall is recorded in docs/16-known-gaps.md. Co-Authored-By: Claude Opus 5.5 <[email protected]>
3.7 KiB
ADR-0017 — Single environment: bare-metal production; dev retired
- Status: Accepted
- Date: 2026-11-08
- Serves: R-PLAT-01, R-ENV-01/02/03, R-STATE-01/02
- Supersedes: ADR-0001 provisioning clause only ("Nodes are provisioned by OpenTofu (libvirt, dev) / bare-metal imaging (prod) + cloud-init, and joined/configured by Ansible"). The rest of ADR-0001 stands: k3s, 3-node HA on embedded etcd, and the bundled components disabled at install.
- Accepted by: operator ruling of 2026-11-08 that the implementation is the accepted state; effective on merge.
Context
ADR-0001 and the original specs assumed two environments: a dev/test cluster of local libvirt KVMs, provisioned by OpenTofu and cloud-init, and a prod cluster of 3 mini-PCs, kept design-only until a later phase.
Delivery did not stay on that path. The workstation host ran out of RAM and disk, so dev moved to VMs
on a Proxmox host. The operator opened Phase 7 on 2026-08-31, and prod was built on 3 HP EliteDesk
Mini bare-metal nodes. On 2026-09-12/13 prod took over the apex home.keithjackson.dev, and the dev
VMs were stopped. The storage pools of the host those VMs ran on then moved to a standalone NAS, and
the migration plan retires that host.
Keeping "dev/test" in the specification now describes something that does not exist. It also leaves R-ENV-01 and R-ENV-03 unsatisfiable as written.
Decision
The platform has one live environment: prod, 3× mini-PC bare metal.
- Create is an imaged, checklist-driven operator step: there is no hypervisor API to call on
bare metal. The checklist is
infra/PROD-PROVISIONING.mdin the implementation repo. - Baseline, cluster-join and manage are code: Ansible owns all of them, including the first-boot baseline that cloud-init used to carry. Cloud-init is not part of node provisioning.
- OpenTofu is not part of node provisioning.
- The Kubernetes API has one HA endpoint, a kube-vip virtual IP across the 3 servers. The address a joining node uses during a cold bootstrap is deliberately a different one, because the virtual IP does not exist until a cluster does.
- GitOps configuration stays one base plus an environment-scoped overlay. No second environment exists, but the separation is kept, so a future environment needs overrides only.
- With no staging surface, the safeguard is the merge gate: every change reaches prod through the PR gate and Flux. Destructive or fault-injecting tests against prod are deliberate, scheduled exercises.
Alternatives considered
- Keep a dev cluster on Proxmox. Rejected: the migration plan retires that host, and dev does not move to the NAS, which is storage only.
- Rebuild dev as local KVMs on the workstation. Rejected: that is the path already abandoned for lack of RAM and disk.
- Drive bare metal through Cluster API or PXE automation. Deferred: imaging plus Ansible is sufficient and lower-complexity for 3 nodes.
Consequences
- The spec stops gating work on a dev cluster; R-ENV-01/02/03 and R-PLAT-01 are reworded to match.
- Conformance runs against prod. There is no separate cluster on which to absorb a bad change, so the static gate and the discipline around fault injection carry more weight.
- Node-rebuild is exercised by hand rather than by a destroy/rebuild pipeline; a node is reimaged and rejoined through the checklist and Ansible.
- The
clusters/devoverlay,infra/tofuand dev defaults remaining in the implementation repo are inert. Removing them is implementation cleanup, and a conformance check that pins them must change with them. - ADR-0001's note that prod must not go below 3 servers stands, and it has no dev counterpart.