How to install and configure Vagrant with libvirt/KVM Virtualization provider

How to install and configure Vagrant with libvirt/KVM Virtualization provider


Here in this article we will configure Vagrant which is popularly used to setup a virtualized development environment using libvirt virualization provider. We will look at the required packages that need to be installed and also provision a VM using vagrant and setup a basic httpd service.

Test Environment

Fedora 37 Workstation

What is Vagrant

Here are some of the important details about Vagrant tool.

  • It is used to setup a development virtualized environment with ease and quickly
  • It uses a declarative configuration to describe all the requirements and build them through a consistent workflow
  • It is a command line utility for managing the lifecycle of virtual machines
  • Vagrant cloud provides with a public, searchable index of Vagrant boxes with different technologies
  • Vagrant boxes can be created using the Packer, Cloud web interface or the API
  • Vagrant boxes can be versioned to track the lifecycle and make updates and fixes efficiently
  • Vagrant stores the user data ie. boxes and plugins in ~/.vargrant.d directory
  • Vagrant isolates dependencies and their configuration within a single disposable and consistent development environment
  • Primary function of Vagrantfile is to describe the type of machine required for project and how to configure and provision these machines
  • Vagrant actually loads a series of Vagrantfiles, merging the settings as it goes
  • Within each Vagrantfile, you may specify multiple Vagrant.configure blocks
  • Boxes require a provider, a virtualization product, to operate. Before you can use a box, ensure that you have properly installed a supported provider
  • Base boxes are extremely useful for having a clean slate starting point from which to build future development environments

Vagrant basically acts like a wrapper around the virtual machines providers like virtualbox, vmware, libvirt allowing us to build, provision and easily replicate virtual machines environments on different operating systems using common syntax.

If you are interested in watching the video. Here is the YouTube video on the same step by step procedure outlined below.


Step1: Check Hardware Virtualization Support

KVM is installed on Linux as a kernel module, but is still a type 1 hypervisor. KVM has everything Linux has because KVM is a part of Linux. KVM requires a CPU which supports virtualization extensions ie. Intel VT or AMD-V. To check whether you have CPU support, run the following command.

$ egrep '^flags.*(vmx|svm)' /proc/cpuinfo

If this command results in nothing printed, your system does not support the relevant virtualization extensions. You can still use QEMU/KVM, but the emulator will fall back to software virtualization, which is much slower.

Step2: Setup KVM Virtualization

As a first step we need to install a virtualization software on our host system so that our system would support in creating and launching a virtual machine on top of it. Here we are going to install “@virtualization” group which will install all the required packages for setting up a virtualized platform.

$ sudo dnf install @virtualization

By default, libvirt will create a private network for your guests on the host machine. This private network will use a 192.168.x.x subnet and not be reachable directly from the network the host machine is on.

Step3: Install Vagrant

Now let’s install vagrant and along with that we are also installing some of the dependent packages. ansible is for configuration management and libvirt is toolkit for interacting with the virtualization capabilities. The vagrant-sshfs plugin adds synced folder support for mounting folders from the Vagrant host into the Vagrant guest via SSHFS.

$ sudo dnf install ansible libvirt libvirt-devel vagrant-libvirt vagrant-sshfs vagrant-hostmanager

Step4: Install Vagrant Plugins

The vagrant-libvirt plugin that adds a Libvirt provider to Vagrant, allows Vagrant to control and provision machines via Libvirt toolkit. . The vagrant-hostmanager is a Vagrant plugin that manages the hosts file on guest machines.

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

$ vagrant plugin install vagrant-hostmanager
Installing the 'vagrant-hostmanager' plugin. This can take a few minutes...
Building native extensions. This could take a while...
Fetching vagrant-hostmanager-1.8.10.gem
Installed the plugin 'vagrant-hostmanager (1.8.10)'!

Step5: Enable and Start libvirtd and virtnetworkd

Once all the required virtualization software are installed. Let’s start up the libvirtd and virtnetworkd services as shown below.

$ sudo systemctl enable libvirtd
$ sudo systemctl start libvirtd
$ sudo systemctl enable virtnetworkd.service
$ sudo systemctl start virtnetworkd.service

Step6: Generate Vagrantfile

Here in this step we are going to launch a VM using vagrant and libvirt as the provider. “vagrant init” command will provide us with a template Vagrantfile in the current working directory which can be modified as per our requirement. Let us first create a Vagrantfile as shown below.

$ vagrant init

Update the generated Vagrantfile as shown below.

$ cat Vagrantfile 
# -*- mode: ruby -*-
# vi: set ft=ruby :

# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
Vagrant.configure("2") do |config|
  # The most common configuration options are documented and commented below.
  # For a complete reference, please see the online documentation at

  # Every Vagrant development environment requires a box. You can search for
  # boxes at = "fedora/38-cloud-base"

  # Disable automatic box update checking. If you disable this, then
  # boxes will only be checked for updates when the user runs
  # `vagrant box outdated`. This is not recommended.
  # config.vm.box_check_update = false

  # Create a forwarded port mapping which allows access to a specific port
  # within the machine from a port on the host machine. In the example below,
  # accessing "localhost:8080" will access port 80 on the guest machine.
  # NOTE: This will enable public access to the opened port "forwarded_port", guest: 80, host: 8080

  # Create a forwarded port mapping which allows access to a specific port
  # within the machine from a port on the host machine and only allow access
  # via to disable public access
  # "forwarded_port", guest: 80, host: 8080, host_ip: ""

  # Create a private network, which allows host-only access to the machine
  # using a specific IP.
  # "private_network", ip: ""

  # Create a public network, which generally matched to bridged network.
  # Bridged networks make the machine appear as another physical device on
  # your network.
  # "public_network"

  # Share an additional folder to the guest VM. The first argument is
  # the path on the host to the actual folder. The second argument is
  # the path on the guest to mount the folder. And the optional third
  # argument is a set of non-required options.
  # config.vm.synced_folder "../data", "/vagrant_data"

  # Disable the default share of the current code directory. Doing this
  # provides improved isolation between the vagrant box and your host
  # by making sure your Vagrantfile isn't accessable to the vagrant box.
  # If you use this you may want to enable additional shared subfolders as
  # shown above.
  # config.vm.synced_folder ".", "/vagrant", disabled: true

  # Provider-specific configuration so you can fine-tune various
  # backing providers for Vagrant. These expose provider-specific options.
  # Example for VirtualBox:
  config.vm.provider "libvirt" do |v|
    # Display the VirtualBox GUI when booting the machine
  #   vb.gui = true
    # Customize the amount of memory on the VM:
    v.memory = "1024"
    v.cpus = "2"
  # View the documentation for the provider you are using for more
  # information on available options.

  # Enable provisioning with a shell script. Additional provisioners such as
  # Ansible, Chef, Docker, Puppet and Salt are also available. Please see the
  # documentation for more information about their specific syntax and use.
  config.vm.provision "shell", inline: <<-SHELL
    dnf update
    dnf install -y httpd
    systemctl start httpd.service
    systemctl enable httpd.service

Step7: Launch VM

By default Vagrant uses VirtualBox as the default virtualization provider. In order to override this default we need to export an environment variable as shown below. We can update the “.bashrc” file in our home directory with the following to override the default.

$ cat ~/.bashrc 
# User specific aliases and functions

Now its time to launch our VM using the Vagrantfile as shown below.

$ vagrant up

In case you are unable to override the default virtualization provider you can manually specify the “–provider” as shown below.

$ vagrant up --provider=libvirt

Once the VM is up and running you can verify the HTTP service using the below URL.

URL - http://localhost:8080/

Hope you enjoyed reading this article. Thank you..