Virtualization

How To Use Vagrant with Libvirt (KVM) on Linux

Step 1: Install KVM and Vagrant

For installation of KVM on Linux, we have some articles already baked for you.

Original content from computingforgeeks.com - post 2278

For Vagrant installation, check below guides:

Step 2: Installing Vagrant plugin

Once you have Vagrant and KVM installed, you should be ready to install a libvirt plugin so that you can start managing KVM Virtual machines using Vagrant.

But first ensure libvirt development package is installed:

  • Rocky / AlmaLinux / CentOS Stream 9:
sudo dnf config-manager --set-enabled crb
sudo yum -y install ruby libvirt-devel
sudo yum -y groupinstall "Development Tools"
  • Rocky / AlmaLinux 8:
sudo dnf config-manager --set-enabled powertools
sudo yum -y install ruby libvirt-devel
sudo yum -y groupinstall "Development Tools"

Then install Vagrant libvirt plugin:

$ vagrant plugin install vagrant-libvirt
Installing the 'vagrant-libvirt' plugin. This can take a few minutes...
Building native extensions. This could take a while...
Building native extensions. This could take a while...
Fetching formatador-1.1.0.gem
Fetching fog-core-2.6.0.gem
Fetching fog-xml-0.1.5.gem
Fetching fog-json-1.2.0.gem
Fetching fog-libvirt-0.13.2.gem
Fetching diffy-3.4.3.gem
Fetching vagrant-libvirt-0.12.2.gem
Installed the plugin 'vagrant-libvirt (0.12.2)'!

If you encounter an error like below:

ERROR: Failed to build gem native extension.

current directory: /home/jmutai/.vagrant.d/gems/2.5.1/gems/nokogiri-1.8.4/ext/nokogiri
/usr/bin/ruby -r ./siteconf20180704-25314-14hvlbq.rb extconf.rb
checking if the C compiler accepts ... yes
Building nokogiri using system libraries.
pkg-config could not be used to find libxml-2.0
Please install either `pkg-config` or the pkg-config gem per
gem install pkg-config -v "~> 1.1"

Then run the commands:

gem install nokogiri
vagrant plugin install pkg-config

And retry installing the plugin.

vagrant plugin install vagrant-libvirt

Once the installation is complete, you can confirm that the plugin has been installed using the following command:

$ vagrant plugin list
vagrant-libvirt (x.y.z, global)

Step 3: Downloading Vagrant boxes

A Vagrant box for Libvirt is a tar archive with 3 files in it.

  • A base VagrantFile
  • Th metadata.json file
  • QCOW2 image

If you are interested in building your own Vagrant boxes, have a look at using Packer and Packer build templates for Vagrant on chef/bento github repo. It will help you to easily get started.

In this example, we’re going to use a ready template. Let add Ubuntu 22.04 and Debian 12 boxes.

$ vagrant box add generic/debian12 --provider=libvirt
==> box: Loading metadata for box 'generic/debian12'
    box: URL: https://vagrantcloud.com/api/v2/vagrant/generic/debian12
==> box: Adding box 'generic/debian12' (v4.3.12) for provider: libvirt (amd64)
    box: Downloading: https://vagrantcloud.com/generic/boxes/debian12/versions/4.3.12/providers/libvirt/amd64/vagrant.box
    box: Calculating and comparing box checksum...
==> box: Successfully added box 'generic/debian12' (v4.3.12) for 'libvirt (amd64)'!

Add Ubuntu 22.04 Vagrant box:

$ vagrant box add generic/ubuntu2204 --provider=libvirt
==> box: Loading metadata for box 'generic/ubuntu2204'
    box: URL: https://vagrantcloud.com/api/v2/vagrant/generic/ubuntu2204
==> box: Adding box 'generic/ubuntu2204' (v4.3.12) for provider: libvirt (amd64)
    box: Downloading: https://vagrantcloud.com/generic/boxes/ubuntu2204/versions/4.3.12/providers/libvirt/amd64/vagrant.box
    box: Calculating and comparing box checksum...
==> box: Successfully added box 'generic/ubuntu2204' (v4.3.12) for 'libvirt (amd64)'!

Check the list of boxes presents locally.

$ vagrant box list   
generic/debian12   (libvirt, 4.3.12, (amd64))
generic/ubuntu2204 (libvirt, 4.3.12, (amd64))

Step 4: Create Libvirt VM Vagrantfile

Vagrant needs a configuration file to get the details and settings for a VM to be created. Let’s create a single VM Vagrantfile.

mkdir ~/vagrant-vms && cd ~/vagrant-vms

Create a Vagrantfile

vim Vagrantfile

content similar to below:

# -*- mode: ruby -*-
# vi: set ft=ruby :

ENV['VAGRANT_DEFAULT_PROVIDER'] = 'libvirt'


Vagrant.configure("2") do |config|

  ##### DEFINE VM #####
  config.vm.define "debian-12" do |config|
  config.vm.hostname = "debian12"
  config.vm.box = "generic/debian12"
  config.vm.box_check_update = false
  #config.vm.network "private_network", ip: "192.168.18.9"
  config.vm.provider :libvirt do |v|
    v.memory = 1024
    end
  end
end

To bring the VM up, run:

$ vagrant up
Bringing machine 'debian-12' up with 'libvirt' provider...
[fog][WARNING] Unrecognized arguments: libvirt_ip_command
==> debian-12: Uploading base box image as volume into Libvirt storage...
==> debian-12: Creating image (snapshot of base box volume).
==> debian-12: Creating domain with the following settings...
==> debian-12:  -- Name:              vagrant-vms_debian-12
==> debian-12:  -- Description:       Source: /home/rocky/vagrant-vms/Vagrantfile
==> debian-12:  -- Domain type:       kvm
==> debian-12:  -- Cpus:              2
==> debian-12:  -- Feature:           acpi
==> debian-12:  -- Feature:           apic
==> debian-12:  -- Feature:           pae
==> debian-12:  -- Clock offset:      utc
==> debian-12:  -- Memory:            1024M
==> debian-12:  -- Base box:          generic/debian12
==> debian-12:  -- Storage pool:      default
==> debian-12:  -- Image(vda):        /var/lib/libvirt/images/vagrant-vms_debian-12.img, virtio, 128G
==> debian-12:  -- Disk driver opts:  cache='default'
==> debian-12:  -- Graphics Type:     vnc
==> debian-12:  -- Video Type:        cirrus
==> debian-12:  -- Video VRAM:        256
==> debian-12:  -- Video 3D accel:    false
==> debian-12:  -- Keymap:            en-us
==> debian-12:  -- TPM Backend:       passthrough
==> debian-12:  -- INPUT:             type=mouse, bus=ps2
==> debian-12: Creating shared folders metadata...
==> debian-12: Starting domain.
==> debian-12: Domain launching with graphics connection settings...
==> debian-12:  -- Graphics Port:      5900
==> debian-12:  -- Graphics IP:        127.0.0.1
==> debian-12:  -- Graphics Password:  Not defined
==> debian-12:  -- Graphics Websocket: 5700
==> debian-12: Waiting for domain to get an IP address...
==> debian-12: Waiting for machine to boot. This may take a few minutes...
    debian-12: SSH address: 192.168.121.75:22
    debian-12: SSH username: vagrant
    debian-12: SSH auth method: private key
    debian-12: 
    debian-12: Vagrant insecure key detected. Vagrant will automatically replace
    debian-12: this with a newly generated keypair for better security.
    debian-12: 
    debian-12: Inserting generated public key within guest...
    debian-12: Removing insecure key from the guest if it's present...
    debian-12: Key inserted! Disconnecting and reconnecting using new SSH key...
==> debian-12: Machine booted and ready!
==> debian-12: Setting hostname...

Vagrant will create a Linux bridge on the host system.

$ brctl show virbr1
bridge name	bridge id		STP enabled	interfaces
virbr1		8000.5254005351c7	yes		virbr1-nic
							vnet0

$ ip addr show dev virbr1
8: virbr1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 52:54:00:53:51:c7 brd ff:ff:ff:ff:ff:ff
    inet 192.168.121.1/24 brd 192.168.121.255 scope global virbr1
       valid_lft forever preferred_lft forever

Run virsh list to see if you’ll get a list of VMs.

$ virsh list          
 Id   Name                    State
---------------------------------------
 1    vagrant-vms_debian-12   running

To ssh to the VM, use vagrant ssh command.

vagrant ssh
cat /etc/redhat-release 

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 debian-12
  HostName 192.168.121.75
  User vagrant
  Port 22
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /home/rocky/vagrant-vms/.vagrant/machines/debian-12/libvirt/private_key
  IdentitiesOnly yes
  LogLevel FATAL
  PubkeyAcceptedKeyTypes +ssh-rsa
  HostKeyAlgorithms +ssh-rsa

To redirect to output to your ssh configuration file, use:

vagrant ssh-config >>~/.ssh/config

Then use ssh command to log in with name configured above:

$ ssh debian-12
vagrant@debian12:~$

To shut down the VM, run:

vagrant@debian12:~$ exit
$ vagrant halt
==> debian-12: Attempting graceful shutdown of VM...

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

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

Step 5: Build your own Vagrant box (Optional)

You need packer installed for this to work. Check:

Then clone bento Github repo.

cd ~/
git clone https://github.com/chef/bento
cd bento/packer_templates/scripts
cd ubuntu

To build Vagrant box of CentOS Stream 8 run:

$ packer build -only qemu -var "headless=true" centos-stream-8-x86_64.json
==> qemu: Gracefully halting virtual machine...
==> qemu: Converting hard drive...
==> qemu: Running post-processor: vagrant
==> qemu (vagrant): Creating Vagrant box for 'libvirt' provider
 qemu (vagrant): Copying from artifact: ../builds/packer-centos-stream-8-x86_64-qemu/centos-stream-8-x86_64
 qemu (vagrant): Compressing: Vagrantfile
 qemu (vagrant): Compressing: box.img
 qemu (vagrant): Compressing: metadata.json
Build 'qemu' finished.
==> Builds finished. The artifacts of successful builds are:
--> qemu: 'libvirt' provider box: ../builds/centos-stream-8.libvirt.box

If the build is successful, ready to import box files will be in the builds directory at the root of the repository.

$ vagrant box add builds/centos-stream-8.libvirt.box --name "centos-stream-8"
==> box: Box file was not detected as metadata. Adding it directly...
==> box: Adding box 'centos-stream-8' (v0) for provider: 
==> box: Successfully added box 'centos-stream-8' (v0) for 'libvirt'!

Verify the box is installed.

 vagrant box list

Other articles:

Keep reading

Install KVM and Virt-Manager on Arch Linux Virtualization Install KVM and Virt-Manager on Arch Linux Virsh Commands Cheatsheet for KVM Virtual Machine Management KVM Virsh Commands Cheatsheet for KVM Virtual Machine Management Install KVM on Debian 13 / Debian 12: Complete Guide KVM Install KVM on Debian 13 / Debian 12: Complete Guide Run Docker (OCI) Images as LXC Containers on Proxmox VE Containers Run Docker (OCI) Images as LXC Containers on Proxmox VE PC Build Guides for Homelabs, AI, and Self-Hosting Proxmox PC Build Guides for Homelabs, AI, and Self-Hosting How To Install and Use KVM on CentOS Stream 9|8 CentOS How To Install and Use KVM on CentOS Stream 9|8

Leave a Comment

Press ESC to close