Libvirt is a set of software tools to manage virtual machine components such as network and storage. Libvirt provdies an abstraction layer hiding the differences across hypervisors such as KVM, Xen, VMWare ESXi, etc.. to avoid having to worry about the intricacies of each hypervisors management tool.

Using the vagrant-libvirt provider with vagrant has some advantages over the Virtualbox provider. For example:

  • Parallel spin up of virtual machines, reducing lab creation time.
  • The ability to create UDP tunnels between host interfaces so VLAN tags are not stripped.
  • Predictably control the IP address the guest VM receives on the management interface.

This post will cover installing libvirt and the libvirt-vagrant plugin on ubuntu 1604 and assumes you already have a working install of Vagrant.


Install dependancy packages with apt

sudo apt install -y qemu-kvm libvirt-bin
sudo apt install -y libxslt-dev libxml2-dev libvirt-dev zlib1g-dev ruby-dev

Add yourself to the libvirtd group.

sudo adduser $USER libvirtd

Install virtinst package.

sudo apt install -y virtinst

Install the vagrant-libvirt vagrant plugin

vagrant plugin install vagrant-libvirt

We need to create a virtual network that will be used by Vagrant for the management interfaces. Create a file named vagrant-libvirt-net.xml that describes the vagrant-libvirt network with the below contents.

<network connections='1'>
  <forward mode='nat'>
      <port start='1024' end='65535'/>
  <bridge name='virbr1' stp='on' delay='0'/>
  <ip address='' netmask=''>
      <range start='' end=''/>

Now add the vagrant-libvirt virtual network.

virsh net-define vagrant-libvirt-net.xml

The vagrant-libvirt network was added but is not yet active and will not autostart on boot.

virsh net-list

# output

Name                 State      Autostart     Persistent
 default             active     yes           yes
 vagrant-libvirt     inactive

Start and enable vagrant-libvirt network.

virsh net-start vagrant-libvirt
virsh net-autostart vagrant-libvirt

Confirm vagrant-libvirt network is active and will autostart on boot.

virsh net-list

# output

 Name                 State      Autostart     Persistent
 default              active     yes           yes
 vagrant-libvirt      active


Now that libvirt and the vagrant-libvirt plugin are installed lets fire up a vagrant virtual machine.

Create a test directory.

mkdir ~/cumulus-libvirt-test
cd ~/cumulus-libvirt-test

Add a Vagrantfile to the test directory.

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

Vagrant.configure("2") do |config| = "CumulusCommunity/cumulus-vx"

Now vagrant up . Note: If you have not previously downloaded the CumulusCommunity/cumulus-vx base box it will be downloaded.

vagrant up --provider=libvirt

# output

Bringing machine 'default' up with 'libvirt' provider...
==> default: Creating image (snapshot of base box volume).
==> default: Creating domain with the following settings...
==> default:  -- Name:              cumulus-libvirt-test_default
==> default:  -- Domain type:       kvm
==> default:  -- Cpus:              1
==> default:  -- Feature:           acpi
==> default:  -- Feature:           apic
==> default:  -- Feature:           pae
==> default:  -- Memory:            512M
==> default:  -- Management MAC:
==> default:  -- Loader:
==> default:  -- Base box:          CumulusCommunity/cumulus-vx
==> default:  -- Storage pool:      default
==> default:  -- Image:             /var/lib/libvirt/images/cumulus-libvirt-test_default.img (4G)
==> default:  -- Volume Cache:      default
==> default:  -- Kernel:
==> default:  -- Initrd:
==> default:  -- Graphics Type:     vnc
==> default:  -- Graphics Port:     5900
==> default:  -- Graphics IP:
==> default:  -- Graphics Password: Not defined
==> default:  -- Video Type:        cirrus
==> default:  -- Video VRAM:        9216
==> default:  -- Sound Type:
==> default:  -- Keymap:            en-us
==> 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 SSH to become available...
    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: Configuring and enabling network interfaces...
==> default: Installing rsync to the VM...
==> default: Rsyncing folder: /home/bradmin/cumulus-libvirt-test/ => /vagrant

Confirm you can login to the box.

# Host shell

vagrant ssh

# Now in vagrant box shell

Welcome to Cumulus VX (TM)

Cumulus VX (TM) is a community supported virtual appliance designed for
experiencing, testing and prototyping Cumulus Networks' latest technology.
For any questions or technical support, visit our community site at:

The registered trademark Linux (R) is used pursuant to a sublicense from LMI,
the exclusive licensee of Linus Torvalds, owner of the mark on a world-wide

Lastly a bit of cleanup.

# back in host shell

vagrant destroy -f

# output

==> default: Removing domain...


The Libvirt provider for Vagrant is a great way to manage guests as it provides more flexibility and control than the Virtualbox provider. In a future blog I will show you how to create UDP tunnels for guest point to point interfaces and control the IP address that is assigned to the management interface by Vagrant.