Prerequisites¶
Overview¶
This document outlines the system requirements and software prerequisites needed to set up the infra-lab environment. Ensure all requirements are met before proceeding with the infrastructure deployment.
Lab-only shortcuts
This guide trades some security for simplicity (passphrase in an environment variable, a shared SSH key, a password passed via TF_VAR_*). Do not reuse these shortcuts for production.
Tested with¶
| Component | Version |
|---|---|
| Host OS | Fedora 44 (the only tested host; other RHEL-family releases are untested, see the libvirt daemon note below) |
| libvirt | 12.0 (Fedora 44 package) |
| OpenTofu | 1.11.5; 1.7 or newer is required for state encryption |
| libvirt provider | dmacvicar/libvirt 0.8.3 (pinned in providers.tf) |
| VM images | Debian 12 (bookworm) GenericCloud, downloaded as latest |
System Requirements¶
Minimum Requirements¶
The lab runs 3 VMs (general01, master01, worker01): 5 vCPUs, 14 GB of VM RAM and about 120 GB of disk in total. Qcow2 volumes are thin-provisioned, but plan for the full size.
| Component | Minimum | Recommended | Notes |
|---|---|---|---|
| CPU | 4 cores | 8+ cores | Must support virtualization (VT-x/AMD-V) |
| Memory | 24GB | 32GB+ | VMs use 14GB; the rest is host overhead and page cache |
| Storage | 150GB | 250GB+ | SSD/NVMe recommended |
| Network | Any | Any | Lab traffic stays on the libvirt NAT network; internet is needed to download images |
| OS | RHEL-family Linux (Fedora, RHEL, Rocky, AlmaLinux) | Fedora 44 | Only Fedora 44 is tested; the commands use dnf |
Virtualization Support¶
Your CPU must support hardware virtualization:
# Check for virtualization support
grep -Ec '(vmx|svm)' /proc/cpuinfo
# Should return > 0 for Intel VT-x or AMD-V
# If 0, check BIOS settings to enable virtualization
Software Installation¶
All commands below assume a regular user with sudo.
Install KVM and Virtualization Tools¶
Enable the libvirt daemons¶
Current libvirt uses modular daemons: one per driver (virtqemud for VMs, virtnetworkd for networks, virtstoraged for storage pools, and so on), each started on demand by its systemd socket. The monolithic libvirtd is deprecated; don’t enable it. Fedora enables the modular sockets by default, so this loop usually changes nothing, but it is safe to run:
for drv in qemu network storage nodedev nwfilter secret interface proxy; do
sudo systemctl enable --now virt${drv}d.socket virt${drv}d-ro.socket virt${drv}d-admin.socket
done
# VM logging and disk locking, used by virtqemud (these have no -ro socket)
sudo systemctl enable --now virtlogd.socket virtlogd-admin.socket virtlockd.socket virtlockd-admin.socket
Host where libvirtd is still enabled
An older version of this guide ran systemctl enable --now libvirtd. Check with systemctl is-enabled libvirtd:
enabledbutsystemctl is-active libvirtdprintsinactive: the modular daemons are already in use (the usual case on Fedora). Disablinglibvirtdonly removes the leftover; running VMs are not affected.active:libvirtdis managing your VMs. Shut down the lab VMs first, because switching daemons disconnects running guests from management untilvirtqemudtakes over.
In both cases:
sudo systemctl disable --now libvirtd.service libvirtd.socket libvirtd-ro.socket libvirtd-admin.socket
# then re-run the loop above
The disable also removes the boot links for virtlogd and virtlockd (libvirtd.service lists them under Also=). Running the loop above, including its last line, restores them.
Allow your user to use the system connection¶
Two things are needed to run virsh against the system instance (qemu:///system, where the lab VMs live) without sudo:
-
Membership of the
libvirtgroup, which polkit uses to authorize access:Log out and back in to apply the group change.
-
LIBVIRT_DEFAULT_URI. Without it,virshrun as a normal user connects to the per-user session instance (qemu:///session) and shows no lab VMs or networks. Persist it in your shell profile (~/.bashrchere; use~/.zshrcfor zsh):
The OpenTofu providers in this repo set qemu:///system explicitly and don’t need the variable.
Install OpenTofu¶
OpenTofu is used for infrastructure automation and VM provisioning. It is not in the default Fedora or Rocky repositories, so add the official OpenTofu repository first. Follow the OpenTofu RPM installation instructions for your distribution, then:
Create an SSH key¶
The VMs are provisioned with your public key through cloud-init. Create one if you don’t have it yet:
You will paste the public key into jarvis-kvm/terraform/vm/main.tf in the Infrastructure Deployment guide.
Encrypt OpenTofu state¶
OpenTofu (1.7+) can encrypt state at rest. This is an OpenTofu feature; Terraform has no equivalent. The encryption block lives inside the terraform {} block of each providers.tf (see jarvis-kvm/terraform/vm/providers.tf for an example). For simplicity, the key provider (PBKDF2) is passed in through the TF_ENCRYPTION environment variable, so the passphrase never lands in the repository.
Generate your own passphrase and persist the variable:
PASSPHRASE="$(openssl rand -hex 24)"
cat >> ~/.bashrc <<EOF
export TF_ENCRYPTION='key_provider "pbkdf2" "key" {
passphrase = "${PASSPHRASE}"
key_length = 32
salt_length = 16
hash_function = "sha256"
}'
EOF
unset PASSPHRASE
source ~/.bashrc
Keep this passphrase
Losing it means losing access to your state. Back it up in a password manager. Storing it in .bashrc is a lab shortcut; for anything real, use a KMS-backed key provider.
Do not reuse state from the repository
Any terraform.tfstate that exists in a clone of this repository was encrypted with the author’s passphrase and cannot be decrypted with yours. If tofu init or tofu plan fails with a decryption error, delete the stale state files under jarvis-kvm/terraform/tf-state/ (they are only the author’s lab state) and start from scratch.
Set the VM admin password¶
The VM module requires admin_password (the local debian account password). Provide it through the environment instead of typing it at each prompt:
export TF_VAR_admin_password="$(openssl rand -base64 18)"
echo "$TF_VAR_admin_password" # store it in your password manager
Install Additional Tools¶
# Packages for cloud-init ISO creation (provider needs mkisofs or a compatible tool)
sudo dnf install -y genisoimage libxslt
# Verify installations
which mkisofs xsltproc
If genisoimage is not available on your release, find the replacement with dnf provides mkisofs (typically xorriso).
Optionally, install the GUI tools if you work from a desktop (not needed on a headless host):
Verification¶
Verify KVM Installation¶
# Check if KVM modules are loaded
lsmod | grep kvm
# Verify the libvirt sockets are listening (the daemons start on first use)
systemctl is-active virtqemud.socket virtnetworkd.socket virtstoraged.socket
systemctl is-active libvirtd # should print inactive
# Test virtualization capabilities
virt-host-validate
Expected lsmod output (module sizes and use counts vary):
Expected virt-host-validate output (the QEMU lines must be PASS; WARN lines such as IOMMU are common and not blocking):
QEMU: Checking for hardware virtualization : PASS
QEMU: Checking if device /dev/kvm exists : PASS
QEMU: Checking if device /dev/kvm is accessible : PASS
QEMU: Checking if device /dev/vhost-net exists : PASS
Verify Network Configuration¶
If the default network is not active:
Verify Storage¶
# Check available disk space
df -h /var/lib/libvirt/images
# Verify libvirt storage pools
virsh pool-list --all
df should report at least the free space listed in the requirements. On a fresh host virsh pool-list --all may be empty or list a default pool. Both cases are handled in the storage pool step.
Troubleshooting¶
| Symptom | Likely cause | Check / fix |
|---|---|---|
grep -Ec '(vmx\|svm)' returns 0 |
Virtualization disabled | Enable VT-x/AMD-V in firmware |
virsh list --all is empty, or virsh errors with Failed to connect socket to '/run/user/.../...-sock' |
Connected to the session instance | Set LIBVIRT_DEFAULT_URI="qemu:///system" (check with virsh uri) |
virsh asks for authentication or permission denied |
Not in the libvirt group yet |
id must list libvirt; log out and in again |
Failed to connect socket to '/var/run/libvirt/virtqemud-sock' |
Modular sockets not enabled | Run the loop in Enable the libvirt daemons |
dnf: No match for argument: tofu |
OpenTofu repo not configured | Add the repo from the OpenTofu install page |
Cleanup¶
Nothing in this page needs cleanup beyond uninstalling packages. Teardown of the lab itself is in Infrastructure Deployment.
Next Steps¶
Once all prerequisites are met and verified:
- Infrastructure Deployment - Deploy VMs and networking
- Kubernetes Setup - Install and configure k0s cluster