Files
home-network-k3s-impl/infra/cloud-init/README.md
T
jakman85andClaude Opus 4.8 39123d7806 infra(cloud-init): deliver baseline via bpg user-data snippet; drop netplan/meta-data templates
bpg/proxmox generates cloud-init network-config (static IP/gw/DNS) and
meta-data natively from the VM initialization block, so remove
network-config.yaml.tftpl and meta-data.yaml.tftpl. The rich first-boot
baseline (users, SSH key, packages, kernel modules, Longhorn /dev/vdb
mount, swap-off) is preserved and shipped as a user-data snippet
referenced by initialization.user_data_file_id. Comments updated
(libvirt -> Proxmox); /dev/vdb still valid (data disk is virtio1).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-08-25 10:23:21 -05:00

52 lines
2.7 KiB
Markdown

# infra/cloud-init — first-boot baseline templates
The "Baseline" node lifecycle stage (docs/02 stage 2). `user-data.yaml.tftpl` is
rendered by OpenTofu (`templatefile()`) and shipped to Proxmox as a **cloud-init
user-data snippet** (`proxmox_virtual_environment_file`, one per node), referenced
by each VM's `initialization.user_data_file_id`. **Authoring only — never applied.**
> Migrated from libvirt: bpg/proxmox generates the cloud-init **network-config**
> (static IP/gateway/DNS) and **meta-data** natively from the VM's `initialization`
> block, so the old `network-config.yaml.tftpl` / `meta-data.yaml.tftpl` templates
> were removed. Only the user-data (this baseline) is still a hand-authored template.
> Requires the `snippets` content type enabled on the image datastore (see ../tofu/README).
Serves **R-ENV-01** (nodes are "created, baselined, cluster-joined, managed as
code") and lays the kernel/OS floor ADR-0001 (k3s) + ADR-0002 (Cilium) +
ADR-0003 (Longhorn) + ADR-0005 (KubeVirt) require.
## Files
- `user-data.yaml.tftpl` — `#cloud-config`: login user + injected SSH **public**
key, hostname, package baseline, kernel modules, sysctls, Longhorn data-disk
mount, swap-off.
`${...}` tokens are **OpenTofu** template vars filled by `../tofu/main.tf`
(`hostname`, `fqdn`, `username`, `ssh_authorized_key`) — they are not cloud-init/Jinja.
IP/gateway/DNS are no longer templated here; bpg/proxmox injects them from the VM's
`initialization` block.
## Baseline (cloud-init's job) vs. Ansible's job
| cloud-init does (here) | Ansible does (T-1.3) |
|---|---|
| user + SSH public key, hostname | install k3s (HA, embedded etcd) |
| static networking | join nodes, disable flannel/kube-proxy/traefik/servicelb |
| `overlay`, `br_netfilter`, `iscsi_tcp`, `dm_crypt`, `nfs` modules | install Cilium (kube-proxy replacement, Gateway API, Hubble) |
| bridge-nf + `ip_forward` sysctls, inotify limits | verify readiness |
| open-iscsi + nfs-common (Longhorn client prereqs) | Flux + SOPS bootstrap handoff |
| mount `/dev/vdb` at `/var/lib/longhorn` | — |
| `swapoff` + strip swap from fstab | — |
### Why these specifics
- **overlay / br_netfilter + bridge-nf-call sysctls** — pod networking / iptables
bridging Cilium and kube-networking need.
- **ip_forward / forwarding** — routing between pods, nodes, and egress.
- **iscsi_tcp + open-iscsi (iscsid) and nfs / nfs-common** — Longhorn attaches
volumes over iSCSI and uses the NFS client for backup/RWX (ADR-0003).
- **dm_crypt** — headroom for Longhorn volume encryption.
- **swap off** — kubelet/k3s expectation.
- **qemu-guest-agent** — lets libvirt/tofu read guest state.
Nested-virt for KubeVirt (Phase 5) comes from the tofu `host-passthrough` CPU
mode, not from here.