Phase 1: a golden image, and why SeaBIOS won this round
Building the cloud-init template every VM clones from — and learning the hard way that UEFI + cloud images + a serial console hides your boot failures.
Phase 1 is the toolchain and the golden image: one cloud-init template that every future VM clones from. Get it right once, stamp it out forever. I got it wrong twice first.
Cloud image, not the installer ISO
The template is built from the distro’s cloud image — a pre-installed disk with cloud-init baked in — not the live-server ISO. The ISO is an installer; you’d have to script an unattended install and reboot for every clone. The cloud image you just clone, and cloud-init paints on the hostname, user, SSH key and static IP at first boot. It’s the whole reason a clone is ready in seconds.
The firmware trap
I built the template with UEFI (OVMF) and a serial-only console, thinking ahead to GPU passthrough. The first clone booted to a black screen at “starting serial terminal” and never got an IP. The trap: under UEFI, early boot writes to the emulated VGA, which I’d disabled — so the screen stays blank while the real failure happens invisibly. SeaBIOS boots these cloud images with zero drama. I switched the base template to SeaBIOS, kept a visible console, and parked UEFI for the one host that genuinely needs it.
If you can’t see the console, you’re not debugging a boot — you’re guessing at one.
The other two gotchas
A tiny VM with too little RAM doesn’t boot slowly — it kernel-panics on memory mid-cloud-init. And pinning a “latest” cloud image by URL bites you the day upstream rebuilds it: pin a dated snapshot and verify its checksum, or your cache and the published hash quietly disagree.
Next: Phase 2 — internal DNS, and a proper chicken-and-egg.