Jeff Li

Be another Jeff

A Beginner's Guide for Vagrant

Introduction

Vagrant is a tool developed at HashiCorp intended to relieve the effort to setup development environment. According to its document, Vagrant is able to “create and configure lightweight, reproducible, and portable development environments”. It relizes the vision through virtualization technologies like VirtualBox. By the way, besides Vagrant, HashiCorp also deliver several open source DevOps tools which are really cool. I suggest spending some time on exploring their products if you are interested in DevOps.

The biggest pain point Vagrant solves is how to boot up a consistent development environment in every host. The benefit is obvious.

  • Boot up a consistent development environment anywhere.
    • If you have multiple laptops, it makes you work seamlessly with any one of them.
    • The development environment is able to be shared among the whole team. There is no need for new team members to spend a day on setting up the environment.
  • The whole development environment is defined in Vagrantfile which is Ruby code in fact. That means the environment can be versioned with version control system like Git and thus could be shared easily.

Getting Started

As mentioned before, Vagrant is built on virtualization, so before getting your hands dirty, you need

From the doc, it is very easy to boot up a virtual machine.

1
2
vagrant init centos/7
vagrant up

Here is the list of what actually happen.

  • The Vagrant command line tool create a Vagrantfile with following content which indicates that vagrant should boot up a virtual machine based on the OS image called centos/7.
1
2
3
Vagrant.configure(2) do |config|
  config.vm.box = "centos/7"
end
  • Vagrant tries to locate the OS image in the local image repo. If not found , it attempts to download the image from HashiCorp’s box search service. The path of local image repo is $HOME/.vagrant.d/boxes.

  • Create a virtual machine based on the OS image

For now, we have a running virtual machine. Imagine the day you booted up a VM by *.iso image, life becomes pretty easy now. Next we can control the VM by running vagrant ssh. This seems like magic but if you run ps -ef | grep vagrant, you can see something like this

1
ssh vagrant@127.0.0.1 -p 2222 -o Compression=yes -o DSAAuthentication=yes -o LogLevel=FATAL -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o IdentitiesOnly=yes -i $PWD/.vagrant/machines/default/virtualbox/private_key

That means vagrant ssh connects to the VM by calling the ssh utility and nothing else. Wait, why the host is 127.0.0.1 ? We’ll check this out in another blog post dedicated to Vagrant network.

How It Works

Essentially, Vagrant provides the features:

  • A nearly hypervisor-agnostic abstraction for managing virtual machines.
  • A way to define the development environment with code. A typical Vagrant development environment includes 2 parts
    • A virtual machine
    • Toolchain like GCC, lib dependencies and Java running in the virtual machine

Let’s see how Vagrant makes it.

Provider

Provider means the type of underlying virtualization technology. Though it is able to manage virtual machines, Vagrant is not a hypervisor itself. Instead, it is just abstraction of managing virtual machines in different hypervisors. That is why we said that hypervisor is a prerequisite for Vagrant.

Vagrant supports multiple types of hypervisor such as VirtualBox, VMware Fusion, VMware Workstation, Hyper-V and Docker. It is worth mentioning that thanks to the plugable provider architecture, Vagrant is able to manage virtual machines in cloud service like AWS, DigitalOcean, VMware vSphere, OpenStack besides hypervisors mentioned before.

Box

Box packages OS images required by the underlying hypervisor to run the virtual machine. Typically, each hypervisor has its own OS image format. Thus when building or downloading boxes, you have to choose the target hypervisor. Boxes are organized in local repo located in $HOME/.vagrant.d/boxes. There are multiple ways to add a box to the local box repo.

  • From HashiCorp’s box discovery service. You can search the OS box you want to run and add it to the local repo by vagrant box add command. Note, you should ALWAYS download the boxes you trust. Fortunately, some popular OS distributions like CentOS and Ubuntu provide the OS boxes officially. HashiCorp provides some boxes too.
  • Use Packer, another tool from HashiCorp to build boxes from iso images. Chef provides a whole bunch of Packer templates in GitHub to make life much more easier.
  • Create box from existing virtual machines running in different hypervisor. See the doc for more detail.

For new Vagrant users, the first method should be preferred because it is easy. For example, a CentOS 7 box could be added by one command line vagrant box add centos/7. The box is trusted because it is distributed officially.

Tip: In some districts like China mainland, it would takes several hours to download the whole box and the download has to be restarted from the begin if any error occurs during transfer which is really painful sometime. A workaround is using some download tools like Thunder to download Vagrant box manually to local hostand then add it to the box repo.

Provisioner

The example doesn’t leverage any provisioner but we have mentioned that one of the essential parts of a development environment is the toolchain. It is impractical to package all the development tools in a box thus the Vagrant provides facility to customize the virtual machine.

There are many deveops tools available to automate configuration management such as Ansible, Puppet, SaltStack and Chef. Vagrant does not reinvent the wheel. Instead, it makes an abstract on different tools so the users could choose any technique they want. The tools are called provisioners.

Supported provisioner list could be found in the doc. You could choose any one you want. If you don’t have experience with any tool yet, I strongly recommend Anislbe because it is simple yet powerful.

What is Next

Vagrant is a powerful tool. It is impossible to cover everything in a single post. Here are some other interesting topics deserves to be explored.

  • Provisioner: We don’t show any usage about provisioner in this post. However, it is essential for customizing a envrionment. Ansible should be considered if you are a developer since it is lightweight and easy to learn.
  • QEMU provider: VirtualBox is great and most of time it is adequate. But it does not support nested virtualzation which is the ability to run virtual machines within another virtual machine. Most of hypervisors like VMware Fusion, Hyper-V and QEMU except VirtualBox support such a feature. Nested virtualization is very useful when creating demo cluster. There is also a company named Ravello who has been acquired by Oracle focusing on nested virtualzation technique. Hyper-V is not cross-platform and VMware Fusion/Workstation is charged. Vagrant provider for VMware Fusion/Workstation is also charged. So QEMU is another provider worthy playing with.
  • Docker provider: As one of the hottest techniques, Docker is worthy noting. Compared with hypervisors like VirtualBox, Docker is much much more lightweight. It is not a hypervisor, but it does provide some abstraction of a virtual machine. Its overhead is very low too which makes it is easy to boot dozens of Docker containers in you laptop. Of course, it is not as versatile as hypervisors but if it meets your need,it would be a good choices.
  • Network: Many new users will be confused on the network configuration of Vagrant. My suggestion is learning the network in hypervisor before you go ahead with Vagrant. VirtualBox’s Network document is a good source to refer.

Comments