Ansible playbook to configure homelab servers as KVM hypervisors on Ubuntu 24.04 (Noble).
- Installs KVM/QEMU, libvirt, and bridge-utils
- Configures a bridged network interface (
br0) over anyen*/et*NIC for VM connectivity - Sets up GPU passthrough via VFIO — blacklists host GPU drivers, writes kernel cmdline args, and updates initramfs
- Resizes the LVM volume group (
ubuntu-vg) across all root disks and expands the logical volume to 95% - Creates
/datafor VM disk image storage (owned bylibvirt-qemu:kvm) - Configures avahi/mDNS restricted to
br0for.localresolution - Sets CPU governor to
performancevia a systemd oneshot service - Disables unattended upgrades to prevent unexpected reboots
- Creates a restricted
wakeletSSH user whose only capability is triggering a clean shutdown (used by the wakelet HomeKit bridge for Siri/Home app power control) - Optionally installs and enables
vm-builder-agentfrom GitHub release assets, including its systemd service and mTLS settings
| Host | GPU | Root disks |
|---|---|---|
nvidia-1.local |
NVIDIA RTX 4080 SUPER | 2× NVMe |
sparkle-1.local |
Intel Arc B570 | 1× NVMe |
ansible-playbook main.yamlPrivilege escalation is required (become: true). You will be prompted for the sudo password.
main.yamlkeeps the play-level assertions, task ordering, and handlers.tasks/packages.yamlinstalls shared packages and optional vm-builder-agent runtime dependencies.tasks/gpu.yamlcontains VFIO, GRUB, and GPU driver blacklist configuration.tasks/network.yamlconfigures Avahi and thebr0netplan bridge.tasks/storage.yamlhandles LVM growth and/datacreation.tasks/system.yamlapplies unattended-upgrades and CPU governor settings.tasks/wakelet.yamlmanages the restricted shutdown user.tasks/vm-builder-agent.yamlinstalls Terraform plus the vm-builder-agent service and runtime it depends on.
| Variable | Default | Description |
|---|---|---|
has_gpu |
false |
Enable GPU passthrough tasks |
gpu_pci_ids |
[] |
PCI IDs to bind to vfio-pci (VGA + audio device) — find them with lspci -nn, look for the VGA compatible controller and Audio device lines |
root_disks |
[] |
Disk paths to add to ubuntu-vg for LVM resize |
wakelet_enabled |
false |
Enable wakelet user and shutdown access setup |
wakelet_pubkey |
(set in vars) | SSH public key for the wakelet shutdown user |
vm_builder_agent_enabled |
false |
Enable vm-builder-agent installation and service management |
vm_builder_agent_version |
latest |
Release selector for the vm-builder-agent binary; use latest or a specific GitHub release tag |
vm_builder_agent_trusted_ca_url |
"" |
URL the agent fetches to get the CA used to verify client certificates |
- The playbook installs the published
vm-builder-agentlinux-amd64release binary instead of building from source, so the hypervisors do not need a Go toolchain. - By default the playbook installs the latest published release. Set
vm_builder_agent_versionto a specific release tag such as"v0.1.2"to pin the agent version. - The service uses the upstream
vm-builder-corerepository and the default authorized client CNvm-builder-apiserver. - The service also installs
gitandxsltproc, whichvm-builder-agentandvm-builder-coreneed at runtime. Terraform is installed by the playbook and the service uses/usr/bin/terraform. - The service always starts with agent mTLS enabled on
:8443, uses/etc/vm-builder-agent/privatefor generated TLS material, and stores workspaces in/var/lib/vm-builder-agent/workspaces, matching the upstream example service. - You must provide
vm_builder_agent_trusted_ca_url. The agent fetches that CA at startup and generates its own server cert/key inside/etc/vm-builder-agent/private.