Vagrant is a tool for building and managing virtual machine environments from a single workflow. Combined with the libvirt provider, it lets you spin up KVM-backed VMs on your local Linux workstation using simple declarative configuration files. This guide walks through installing Vagrant with the libvirt/KVM provider on Rocky Linux 10 and AlmaLinux 10, adding Vagrant boxes, and launching your first VM.
Prerequisites
- A server or workstation running Rocky Linux 10 or AlmaLinux 10
- CPU with hardware virtualization support (Intel VT-x or AMD-V)
- Root or sudo access
- At least 4 GB RAM (more recommended if running multiple VMs)
- Internet connectivity to download packages and Vagrant boxes
Start with a system update and reboot to apply any kernel or firmware changes:
sudo dnf -y update && sudo reboot
Step 1: Install KVM and Libvirt on Rocky Linux 10 / AlmaLinux 10
Vagrant with the libvirt provider requires a working KVM hypervisor. Your CPU must support hardware virtualization extensions. Verify this first:
lscpu | grep Virtualization
You should see VT-x (Intel) or AMD-V (AMD) in the output. Install the KVM virtualization stack:
sudo dnf install -y @virt virt-install libvirt-devel qemu-kvm
Enable and start the libvirtd service:
sudo systemctl enable --now libvirtd
Add your user account to the libvirt group so you can manage VMs without sudo:
sudo usermod -aG libvirt $USER
newgrp libvirt
Confirm the service is running:
$ systemctl status libvirtd
● libvirtd.service - Virtualization daemon
Loaded: loaded (/usr/lib/systemd/system/libvirtd.service; enabled; preset: disabled)
Active: active (running)
Also verify that the default NAT network is active. Vagrant uses this network by default for VM connectivity:
$ sudo virsh net-list --all
Name State Autostart Persistent
--------------------------------------------
default active yes yes
If the default network is inactive, start it:
sudo virsh net-start default
sudo virsh net-autostart default
Step 2: Install Vagrant on Rocky Linux 10 / AlmaLinux 10
Vagrant is distributed through the official HashiCorp repository. Add the repo and install Vagrant:
sudo dnf install -y dnf-utils
sudo dnf config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
Install Vagrant:
sudo dnf install -y vagrant
Verify the installation:
$ vagrant --version
Vagrant 2.4.9
Step 3: Install the vagrant-libvirt Plugin
By default, Vagrant uses VirtualBox as its provider. To use KVM/libvirt instead, install the vagrant-libvirt plugin. First, install the build dependencies required to compile the native extensions:
sudo dnf install -y gcc gcc-c++ make cmake ruby-devel libvirt-devel libxml2-devel libxslt-devel zlib-devel libguestfs-tools-c rsync
Now install the plugin:
vagrant plugin install vagrant-libvirt
Confirm the plugin is installed:
$ vagrant plugin list
vagrant-libvirt (0.12.2, global)
Set libvirt as the default Vagrant provider so you do not have to specify it every time. Add this to your shell profile:
echo 'export VAGRANT_DEFAULT_PROVIDER=libvirt' >> ~/.bashrc
source ~/.bashrc
Enable shell autocompletion for Vagrant commands:
vagrant autocomplete install --bash
source ~/.bashrc
Step 4: Configure Firewall for Libvirt
If firewalld is active, the libvirt zone should already be configured. Verify it:
sudo firewall-cmd --get-active-zones
You should see a libvirt zone with the virbr0 interface. If the libvirt zone is missing, add the virtual bridge interface to it:
sudo firewall-cmd --zone=libvirt --change-interface=virbr0 --permanent
sudo firewall-cmd --reload
This allows DHCP (UDP 67-68), DNS (TCP/UDP 53), and general traffic between the host and VMs on the NAT network. If you need VMs to be reachable from other hosts on your LAN, configure a bridged network in libvirt instead of the default NAT.
Step 5: Add Vagrant Boxes for Libvirt
Vagrant boxes are pre-built VM images. You need boxes that were built specifically for the libvirt provider. Browse all available boxes at Vagrant Cloud. Download a few common ones:
### Rocky Linux 10 ###
vagrant box add generic/rocky10 --provider=libvirt
### AlmaLinux 10 ###
vagrant box add generic/alma10 --provider=libvirt
### Ubuntu 24.04 ###
vagrant box add generic/ubuntu2404 --provider=libvirt
### Debian 13 ###
vagrant box add generic/debian13 --provider=libvirt
List your downloaded boxes:
$ vagrant box list
generic/alma10 (libvirt, 4.4.2)
generic/rocky10 (libvirt, 4.4.2)
generic/ubuntu2404 (libvirt, 4.4.2)
Step 6: Create a Vagrantfile and Launch a VM
Create a project directory and initialize a Vagrantfile. This example creates a Rocky Linux 10 VM with 2 GB RAM and 2 CPUs:
mkdir -p ~/vagrant-projects/rocky10 && cd ~/vagrant-projects/rocky10
Create the Vagrantfile:
vim Vagrantfile
Add the following configuration:
# -*- mode: ruby -*-
# vi: set ft=ruby :
ENV['VAGRANT_DEFAULT_PROVIDER'] = 'libvirt'
Vagrant.configure("2") do |config|
config.vm.define "rocky10" do |node|
node.vm.hostname = "rocky10"
node.vm.box = "generic/rocky10"
node.vm.box_check_update = false
node.vm.provider :libvirt do |v|
v.memory = 2048
v.cpus = 2
end
end
end
Boot the VM:
$ vagrant up
Bringing machine 'rocky10' up with 'libvirt' provider...
==> rocky10: Uploading base box image as volume into Libvirt storage...
==> rocky10: Creating image (snapshot of base box volume).
==> rocky10: Creating domain with the following settings...
==> rocky10: -- Name: rocky10_rocky10
==> rocky10: -- Domain type: kvm
==> rocky10: -- Cpus: 2
==> rocky10: -- Memory: 2048M
==> rocky10: -- Base box: generic/rocky10
==> rocky10: -- Storage pool: default
==> rocky10: Creating shared folders metadata...
==> rocky10: Starting domain.
==> rocky10: Waiting for domain to get an IP address...
==> rocky10: Waiting for machine to boot. This may take a few minutes...
rocky10: SSH address: 192.168.121.45:22
rocky10: SSH username: vagrant
rocky10: SSH auth method: private key
==> rocky10: Machine booted and ready!
==> rocky10: Setting hostname...
Check the VM status:
$ vagrant status
Current machine states:
rocky10 running (libvirt)
The Libvirt domain is running.
Step 7: Connect to and Manage the Vagrant VM
SSH into the running VM:
$ vagrant ssh
[vagrant@rocky10 ~]$ cat /etc/redhat-release
Rocky Linux release 10.0 (Sapphire Leopard)
You can also confirm the VM is visible through virsh on the host:
virsh list --all
The following table covers the essential Vagrant commands you will use regularly:
| Command | Description |
|---|---|
vagrant up | Start and provision the VM |
vagrant ssh | SSH into the running VM |
vagrant halt | Gracefully shut down the VM |
vagrant destroy | Stop and delete the VM and its storage |
vagrant status | Show current state of the VM |
vagrant reload | Restart the VM and re-read the Vagrantfile |
vagrant suspend | Save VM state to disk (pause) |
vagrant resume | Resume a suspended VM |
vagrant box list | List all downloaded boxes |
vagrant box remove NAME | Delete a downloaded box |
To stop the VM:
vagrant halt
To destroy the VM and free up disk space:
vagrant destroy -f
Multi-VM Vagrantfile Example with Libvirt
Vagrant makes it easy to define multiple VMs in a single Vagrantfile. This is useful for testing clustered setups or multi-tier applications. If you prefer Vagrant with VirtualBox, the Vagrantfile syntax is nearly identical – just change the provider block.
vim Vagrantfile
Add the following multi-VM configuration:
# -*- mode: ruby -*-
# vi: set ft=ruby :
ENV['VAGRANT_DEFAULT_PROVIDER'] = 'libvirt'
Vagrant.configure("2") do |config|
# Web server
config.vm.define "web" do |web|
web.vm.hostname = "web-server"
web.vm.box = "generic/rocky10"
web.vm.provider :libvirt do |v|
v.memory = 2048
v.cpus = 2
end
end
# Database server
config.vm.define "db" do |db|
db.vm.hostname = "db-server"
db.vm.box = "generic/rocky10"
db.vm.provider :libvirt do |v|
v.memory = 4096
v.cpus = 2
end
end
end
Start all VMs at once:
vagrant up
SSH into a specific VM by name:
vagrant ssh web
vagrant ssh db
Troubleshooting Common Issues
Plugin build fails with missing headers – Make sure all development libraries are installed. The libvirt-devel, libxml2-devel, and ruby-devel packages are the most commonly missing ones.
Permission denied on /var/lib/libvirt/images – Your user is not in the libvirt group. Run sudo usermod -aG libvirt $USER and log out/back in. You can also check the KVM virtualization setup guide for detailed permission configuration.
VirtualBox and KVM conflict – You cannot run both VirtualBox and KVM at the same time. If you have VirtualBox installed, stop its service before using Vagrant with libvirt:
sudo systemctl stop vboxdrv.service
Default network not active – If vagrant up fails with a network error, start the default libvirt network with sudo virsh net-start default.
Conclusion
Vagrant with the libvirt provider gives you fast, disposable KVM virtual machines managed through simple configuration files. This setup is ideal for testing infrastructure code, spinning up lab environments, and validating multi-node deployments on Rocky Linux 10 or AlmaLinux 10. For production KVM hosts, consider setting up proper storage pools and network configurations beyond the defaults.