How To Use Vagrant with Libvirt on Linux to manage VMs

Vagrant is an open-source software product for building and maintaining portable virtual software development environments; e.g., for VirtualBox, KVM, Hyper-V, Docker containers, VMware, and AWS. It is not a stand-alone virtualization provider. It relies on other virtualization providers such as Virtualbox, Libvirt/KVM, Docker, VMWare to create and run virtual machines.

By default, Vagrant uses Oracle VirtualBox as provider. If more than one providers are installed (E.g. Virtualbox and Libvirt) in your system, it will always start a VM with Virtualbox unless you explicitly provide a specific provider. One of the great features of Vagrant is that users are never tied to a specific virtualization platform. The users can create workflows that work with multiple virtualization providers.

In this guide, we will learn how to use Vagrant with Libvirt KVM provider on Linux.

# Step 1 – Installing KVM

Before proceeding, you need to have KVM installed in your system. I already have KVM installed in my system, please checkout these guides on how to install KVM:

Step 2 – Installing vagrant

Next, we need to make sure that Vagrant is installed. Vagrant is available packaged for most of the distributions, please consult the downloads page here or use your package manager to install.

To confirm that vagrant is installed and working as expected, check it’s version using this command:

➜ vagrant version
Installed Version: 2.2.19
Latest Version: 2.2.19

You're running an up-to-date version of Vagrant!

# Step 3 – Install vagrant-libvirt plugin

In order to run Vagrant virtual machines on KVM, you need to install the vagrant-libvirt plugin. This plugin adds the Libvirt provider to Vagrant and allows Vagrant to control and provision machines via Libvirt.

Install the necessary dependencies for vagrant-libvirt plugin.

➜ vagrant plugin install vagrant-libvirt

Installing the 'vagrant-libvirt' plugin. This can take a few minutes...
Fetching formatador-1.1.0.gem
Fetching fog-core-2.3.0.gem
Fetching fog-json-1.2.0.gem
Fetching nokogiri-1.13.6-x86_64-linux.gem
Fetching fog-xml-0.1.4.gem
Fetching ruby-libvirt-0.8.0.gem
Building native extensions. This could take a while...
Fetching fog-libvirt-0.9.0.gem
Fetching vagrant-libvirt-0.8.2.gem
Installed the plugin 'vagrant-libvirt (0.8.2)'!

Once installation is complete, confirm that it has been registered fine by listing plugins:

➜ vagrant plugin list
vagrant-libvirt (0.8.2, global)

# Step 4 – Use Vagrant With Libvirt KVM Provider

Make sure the Vagrant box that you want to use supports the libvirt provider. To discover vagrant boxes supported by libvirt, just select the “libvirt” option in Vagrant Cloud repository.

For the purpose of this guide, I am going to use a Rocky Linux 8 box.

To add a box, use this command:

vagrant box add generic/rocky8 --provider=libvirt

Check the list of boxes presents locally.

➜ vagrant box list
generic/rocky8 (libvirt, 3.6.14)

Another alternative is to use a project. Create a vagrant project directory and switch to it:

mkdir rocky-vm
cd rocky-vm

Then initialize with the box you want to use:

vagrant init generic/rocky8

Next, run the following command to start the virtual machine:

vagrant up --provider=libvirt

Here, --provider=libvirt option explicitly tells Vagrant to use libvirt KVM to run the virtual machine. Meaning – KVM acts as default provider here.

Sample output:

➜ vagrant up --provider=libvirt

Bringing machine 'default' up with 'libvirt' provider...
==> default: Checking if box 'generic/rocky8' version '3.6.14' is up to date...
==> default: Uploading base box image as volume into Libvirt storage...
==> default: Creating image (snapshot of base box volume).
==> default: Creating domain with the following settings...
==> default:  -- Name:              rocky-vm_default
==> default:  -- Description:       Source: /home/eutychus/rocky-vm/Vagrantfile
==> default:  -- Domain type:       kvm
==> default:  -- Cpus:              2
==> default:  -- Feature:           acpi
==> default:  -- Feature:           apic
==> default:  -- Feature:           pae
==> default:  -- Clock offset:      utc
==> default:  -- Memory:            2048M
==> default:  -- Management MAC:
==> default:  -- Loader:
==> default:  -- Nvram:
==> default:  -- Base box:          generic/rocky8
==> default:  -- Storage pool:      default
==> default:  -- Image(vda):        /var/lib/libvirt/images/rocky-vm_default.img, virtio, 128G
==> default:  -- Disk driver opts:  cache='default'
==> default:  -- Kernel:
==> default:  -- Initrd:
==> default:  -- Graphics Type:     vnc
==> default:  -- Graphics Port:     -1
==> default:  -- Graphics IP:
==> default:  -- Graphics Password: Not defined
==> default:  -- Video Type:        cirrus
==> default:  -- Video VRAM:        256
==> default:  -- Video 3D accel:    false
==> default:  -- Sound Type:
==> default:  -- Keymap:            en-us
==> default:  -- TPM Backend:       passthrough
==> default:  -- TPM Path:
==> default:  -- INPUT:             type=mouse, bus=ps2
==> default: Creating shared folders metadata...
==> default: Starting domain.
==> default: Waiting for domain to get an IP address...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address:
    default: SSH username: vagrant
    default: SSH auth method: private key
    default: Vagrant insecure key detected. Vagrant will automatically replace
    default: this with a newly generated keypair for better security.
    default: Inserting generated public key within guest...
    default: Removing insecure key from the guest if it's present...
    default: Key inserted! Disconnecting and reconnecting using new SSH key...
==> default: Machine booted and ready!

Alternatively you can tell Vagrant to permanently use libvirt as default provider by adding the following environment variable.


Vagrant will create a Linux bridge on the host system.

➜ brctl show virbr1

bridge name	bridge id		STP enabled	interfaces
virbr1		8000.5254009d4555	yes		vnet0

You can also check the ip

➜ ip addr show dev virbr1

9: virbr1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 52:54:00:9d:45:55 brd ff:ff:ff:ff:ff:ff
    inet brd scope global virbr1
       valid_lft forever preferred_lft forever

# Step 5 – Verify that the vm is running

You can verify if the CentOS 7 VM is really running in Libvirt KVM provider from Virsh command line interface.

virsh list

Sample output:

 Id   Name               State
 1    rocky-vm_default   running

Or, use vagrant status command:

➜ vagrant status
Current machine states:

default                   running (libvirt)

The Libvirt domain is running. To stop this machine, you can run
`vagrant halt`. To destroy the machine, you can run `vagrant destroy`.

You can also verify it from a KVM management GUI applications like Virt-manager.

To ssh to the VM, use _vagrant ssh _command.

➜ vagrant ssh

[vagrant@rocky8 ~]$

To output .ssh/config valid syntax for connecting to this environment via ssh, run ssh-config command. You’ll need to place provided output under ~/.ssh/config directory to ssh.

➜ vagrant ssh-config

Host default
  User vagrant
  Port 22
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /home/eutychus/rocky-vm/.vagrant/machines/default/libvirt/private_key
  IdentitiesOnly yes
  LogLevel FATAL

To shut down the VM, run:

➜ vagrant halt

==> default: Attempting graceful shutdown of VM...

To set VM to its initial state by cleaning all data, use vagrant destroy:

➜ vagrant destroy

    default: Are you sure you want to destroy the 'default' VM? [y/N] y
==> default: Removing domain...
==> default: Deleting the machine folder

# Conclusion

In this guide, we learned how to use Vagrant with libvirt KVM provider in Linux. We also looked at how to verify if the virtual machine is running in Libvirt KVM.

Last updated on Mar 20, 2024 17:19 +0300
comments powered by Disqus
Citizix Ltd
Built with Hugo
Theme Stack designed by Jimmy