How to create a vagrant VM from a libvirt vm/image

It cost's me some nerves and time to figure out how to create a vagrant image from a libvirt kvm vm and how to modify an existing one. Thanks to pl_rock from stackexchange for the awesome start.

  • First of all you have to install a new vm as usual. I've installed a new vm with Ubuntu 16.04 LTS. I'm not sure if it's really neccessary but set the root password to "vagrant", just to be sure.
  • Connect to your VM via ssh or terminal and do the following steps.

Create a new user for vagrant:

adduser vagrant

Vagrant user should be able to run sudo commands without a password prompt:

sudo visudo -f /etc/sudoers.d/vagrant


Install ssh-server if that's not already done:

sudo apt-get install -y openssh-server

Create a home directory for your vagrant user and also get the master key:

mkdir -p /home/vagrant/.ssh
chmod 0700 /home/vagrant/.ssh
wget --no-check-certificate \ \
-O /home/vagrant/.ssh/authorized_keys
chmod 0600 /home/vagrant/.ssh/authorized_keys
chown -R vagrant /home/vagrant/.ssh

Open the ssh config "/etc/ssh/sshd_config" and change:

PubKeyAuthentication yes
AuthorizedKeysFile %h/.ssh/authorized_keys
PermitEmptyPasswords no
PasswordAuthentication no

Install additional development packages for the tools to properly compile and install:

sudo apt-get install -y gcc build-essential linux-headers-server

Remove the following file to make sure the network will be configured properly on next boot:

rm -f /etc/udev/rules.d/

After you've made all your changes, shutdown your VM.

Now we have to eventually change the disk format as well as to create additional files

Goto the image folder:

cd /var/lib/libvirt/images/

Create two files that are neccessary for the vagrant box

Create the "metadata.json" file:

"provider"     : "libvirt",
"format"       : "qcow2",
"virtual_size" : 40

Create the "Vagrantfile" file:

Vagrant.configure("2") do |config|
       config.vm.provider :libvirt do |libvirt|
       libvirt.driver = "kvm" = 'localhost'
       libvirt.uri = 'qemu:///system'
config.vm.define "new" do |custombox| = "custombox"
       custombox.vm.provider :libvirt do |test|
       test.memory = 1024
       test.cpus = 1

Now you have to convert your image file to qcow2:

sudo qemu-img convert -f raw -O qcow2 test.img ubuntu.qcow2

Rename the image to ".img" ending:

mv ubuntu.qcow2 box.img

Note: currently,libvirt-vagrant support only qcow2 format. So, don't change the format just rename to box.img, ecause it takes input with name box.img by default.

Create the .box archive with all the created files:

tar cvzf ./metadata.json ./Vagrantfile ./box.img

Add the box to vagrant:

vagrant box add --name custom

Go to any directory where you want to initialize vagrant and run command bellow that will create the Vagrant file:

vagrant init custom

Start the vagrant VM:

vagrant up --provider=libvirt

Note:: If you want to change some settings of an already running vm, just make your changes and do a "shutdown" or "vagrant halt". After that you can commit the changes back to the "backing" file. Just do "qemu-img commit /var/lib/libvirt/images/YOUR-VAGRANT-DEPLOYED-SNAP-FILE". After that you can do a "vagrant up" with your modified image.


Comments powered by Disqus