Test Ansible playbooks locally using a Vagrant VM before deploying to staging/production.Documentation Index
Fetch the complete documentation index at: https://docs.allthingslinux.org/llms.txt
Use this file to discover all available pages before exploring further.
Environments
- dev (Vagrant): Local VM for Ansible testing
- staging (Terraform): Hetzner Cloud VPS for pre-production validation
- production (bare-metal): Physical Hetzner server — not managed by Terraform
Prerequisites
- Vagrant
- vagrant-libvirt + libvirt (KVM) — required; the Debian Trixie box does not support VirtualBox
- dnsmasq — required by libvirt for the default NAT network (DHCP/DNS for VMs)
- SSH key pair for dev access (create if missing):
Setup
Arch Linux
1. Install libvirt and QEMUnewgrp libvirt) for the group change to take effect.
3. Enable and start libvirtd
iptables installed, remove it first (Arch uses iptables-nft):
just dev-up sets VAGRANT_DEFAULT_PROVIDER=libvirt automatically. If running vagrant directly, set export VAGRANT_DEFAULT_PROVIDER=libvirt.
Other distros
Quick Start
Testing Specific Roles
Run only the roles you’re working on to speed up iteration:--check to do a dry run without making changes:
Provider Notes
Thedebian/trixie64 box supports only libvirt (KVM). If Vagrant picks VirtualBox by default, set export VAGRANT_DEFAULT_PROVIDER=libvirt before just dev-up.
Vagrant–libvirt specifics
- Port 2223: vagrant-libvirt skips port forwarding when
id: "ssh"(Vagrant’s default). We useid: "ssh_lh"and port 2223 to avoid duplicate declarations with Vagrant’s built-in 2222. - Synced folders disabled: The default
/vagrantsync uses NFS, which requiresnfs-commonin the guest. That can fail if the VM lacks IPv6 connectivity (apt tries IPv6 first for Debian mirrors). Ansible runs from the host over SSH, so no project files are needed in the VM. - Root SSH: The provisioner copies
.ssh/dev_key.pubto/root/.ssh/authorized_keysand runschown root:rootso sshd accepts the key (files uploaded by Vagrant are owned by the vagrant user).
Troubleshooting
- Provider mismatch / wrong VM state: If you previously used VirtualBox or have stale state, remove
.vagrantand re-runjust dev-up: - Plugin errors: If Vagrant fails to initialize, try
vagrant plugin repairorvagrant plugin expunge --reinstall - Provider not found: Install
vagrant-libvirt(Arch:pacman -S vagrant libvirt) - “Unable to find ‘dnsmasq’ binary”: Libvirt needs dnsmasq for the default NAT network. Install it:
sudo pacman -S dnsmasq(Arch) - “Permission denied (publickey)” for root@127.0.0.1: The provisioner may have left
authorized_keysowned by vagrant. Re-runvagrant provision. If it persists,vagrant sshin and runsudo chown root:root /root/.ssh/authorized_keys. - Port 2223 in use: Change the host port in the Vagrantfile and update
ansible_portinansible/inventory/hosts.yml. - libvirt
virNetworkCreate/guest_natnftables error: The default libvirt NAT network can conflict with nftables on Arch. See libvirt - ArchWiki.-
Flush and reset:
-
Allow virbr0 in nftables: If you use a custom
/etc/nftables.confwithpolicy drop, add: -
Try iptables backend: Create
/etc/libvirt/network.confwithfirewall_backend = "iptables", then restart libvirtd. -
“No such file or directory” on
guest_nat/postrouting: Libvirt needs thenft_natkernel module. Ifmodprobe nft_natfails, reinstall the kernel package:sudo pacman -S linux-zen.
-
Flush and reset:
Notes
- SSH key authentication using
.ssh/dev_key(not committed to git) - SSH available on
127.0.0.1:2223 - VM uses Debian 13 (Trixie) to match production
- Dev target runs full playbook including security and quotas
- Native systemd — all Ansible tasks run as they would on staging/prod