From Fedora Project Wiki

Vagrant is a useful development tool that lowers the barrier to entry to new contributor of your project. With Vagrant, new contributors don't have to spend much time configuring their development environment, but can quickly get one automatically provisioned for them with a few simple commands.

Using Vagrant in Fedora

Fedora's Cloud working group provides Fedora Vagrant boxes for libvirt and Virtualbox. You can see the Fedora 24 Vagrant images here.

To quickly get started with Vagrant on a Fedora host, the Fedora developers have conveniently packaged vagrant-libvirt and a handful of handy Vagrant plugins for you. All you need to do is to install vagrant-libvirt and the plugins you wish to use, write a Vagrantfile for your project, and type "vagrant up" to get started. Here's an example Vagrantfile:

 # -*- mode: ruby -*-
 # vi: set ft=ruby :
 #
 # Copy this file to ``Vagrantfile`` and customize it as you see fit.
 
 VAGRANTFILE_API_VERSION = "2"
 
 Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  # If you'd prefer to pull your boxes from Hashicorp's repository, you can
  # replace the config.vm.box and config.vm.box_url declarations with the line below.
  #
  # config.vm.box = "fedora/25-cloud-base"
  config.vm.box = "f25-cloud-libvirt"
  config.vm.box_url = "https://download.fedoraproject.org/pub/fedora/linux/releases"\
                      "/25/CloudImages/x86_64/images/Fedora-Cloud-Base-Vagrant-25-1"\
                      ".3.x86_64.vagrant-libvirt.box"
 
  # Forward traffic on the host to the development server on the guest.
  # You can change the host port that is forwarded to 5000 on the guest
  # if you have other services listening on your host's port 80.
  config.vm.network "forwarded_port", guest: 5000, host: 80
 
  # This is an optional plugin that, if installed, updates the host's /etc/hosts
  # file with the hostname of the guest VM. In Fedora it is packaged as
  # ``vagrant-hostmanager``
  if Vagrant.has_plugin?("vagrant-hostmanager")
      config.hostmanager.enabled = true
      config.hostmanager.manage_host = true
  end
 
  # Vagrant can share the source directory using rsync, NFS, or SSHFS (with the vagrant-sshfs
  # plugin). Consult the Vagrant documentation if you do not want to use SSHFS.
  config.vm.synced_folder ".", "/vagrant", disabled: true
  config.vm.synced_folder ".", "/home/vagrant/devel", type: "sshfs", sshfs_opts_append: "-o nonempty"
 
  # To cache update packages (which is helpful if frequently doing `vagrant destroy && vagrant up`)
  # you can create a local directory and share it to the guest's DNF cache. Uncomment the lines below
  # to create and use a dnf cache directory
  #
  # Dir.mkdir('.dnf-cache') unless File.exists?('.dnf-cache')
  # config.vm.synced_folder ".dnf-cache", "/var/cache/dnf", type: "sshfs", sshfs_opts_append: "-o nonempty"
 
  # Comment this line if you would like to disable the automatic update during provisioning
  config.vm.provision "shell", inline: "sudo dnf upgrade -y"
 
  # bootstrap and run with ansible
  config.vm.provision "shell", inline: "sudo dnf -y install python2-dnf libselinux-python"
  config.vm.provision "ansible" do |ansible|
      ansible.playbook = "devel/ansible/vagrant-playbook.yml"
  end
 
 
  # Create the "nuancier" box
  config.vm.define "nuancier" do |nuancier|
     nuancier.vm.host_name = "nuancier-dev.example.com"
 
     nuancier.vm.provider :libvirt do |domain|
         # Season to taste
         domain.cpus = 4
         domain.graphics_type = "spice"
         domain.memory = 2048
         domain.video_type = "qxl"
 
         # Uncomment the following line if you would like to enable libvirt's unsafe cache
         # mode. It is called unsafe for a reason, as it causes the virtual host to ignore all
         # fsync() calls from the guest. Only do this if you are comfortable with the possibility of
         # your development guest becoming corrupted (in which case you should only need to do a
         # vagrant destroy and vagrant up to get a new one).
         #
         # domain.volume_cache = "unsafe"
     end
  end
 end


In this example, we're using the Fedora 25 libvirt box and we're assuming that your project has an ansible playbook at the relative path devel/ansible/playbook.yml. Writing ansible playbooks is beyond the scope of this document, and you are free to use config.vm.provision lines to configure your Vagrant guest if you like.

To get started with the above example, simply write the code to a file called Vagrantfile, install vagrant-libvirt, vagrant-sshfs, and optionally vagrant-hostmanager, then run vagrant up:

$ cd ~/devel/my_project
$ vim Vagrantfile  # Write the above Vagrant code here
$ sudo dnf install libvirt vagrant vagrant-libvirt vagrant-sshfs
$ vagrant up

Once your guest is running, you can ssh into the guest. Your code directory from the host will be shared into the guest at the path ~/devel:

$ vagrant ssh
$ [vagrant@localhost ~]$ ls devel/
Vagrantfile

Now you can edit your project on your host, and the changes you make will be shared into the guest's ~/devel/ folder live. This allows you to use your editor of choice (even graphical editors!) on the host, while keeping everything that might "dirty" you host system contained in the guest virtual machine. This example Vagrantfile has also set up a port forward from 5000 in the guest to 5000 on the host, so if there were a web application listening in the guest on port 5000, you could browse to http://localhost:80 on the host to access it. If you installed vagrant-hostmanager, you could also browse http://nuancier-dev.example.com:5000.

When you are done with your Vagrant guest, you can destroy it:

$ vagrant destroy

It is good practice to check in a Vagrantfile.example file in your project's source code, rather than the Vagrantfile itself. This allows new developers a quick way to get started by just copying your example into place, but it also allows each contributor to make the changes they prefer to their individual Vagrantfiles.