My Vagrant Workflow

Why Vagrant

For those who never heard about the Vagrant, it is a very handy way to manage, create and destroy headless virtual machine (VM) environments.

Vagrant's initial support was limited to VirtualBox because it's core was tied with VirtualBox specific code, but recent changes will allow Vagrant to support other VM types[1]. Other VM types will be supported via plugin based providers [2]. At the moment VirtualBox is the default provider. For Vagrant 1.2+, a AWS provider to Vagrant is avilable as plugin, allowing Vagrant to control and provision machines in EC2 and VPC.

Update

This blog post has been updated for Vagrant version 2.

Currently, there are only two supported versions: "1" and "2". Version 1 represents the configuration from Vagrant 1.0.x. "2" represents the configuration for 1.1+ leading up to 2.0.x.

Running a headless [3] virtual machine via Vagrant is not very different from running a virtual machine using a front end. In my opinion Vagrant's has several advantages,

Simplified port forwarding from guest to host and network configuration.

Painless folder sharing between guest and host.

There are so many different reasons to use the Vagrant in your development workflow. But to me it was always about having consistent disposable development environment on my all machines. Also I prefer to isolate my development environment from host operating system in a cleaner way.

Disposable nature of environments created by Vagrant make them perfect fit for developing and testing configuration management scripts.

Installing Vagrant

Prerequisite: First download VirtualBox and install it. Vagrant currently requires VirtualBox 4.0.x or 4.1.x or 4.2.x.

You can download a Vagrant binary for your operating system, or install it as a gem

My Workflow

My Workspace

I have a WorkSpace folder where all my Vagrant instance setups and development projects live. Inside WorkSpace I have project specific folders where each folder has its own Vagrantfile.

mkdir -p ~/WorkSpace/test
cd ~/WorkSpace/test

My Base Box

A Vagrant base box is tar package in a specific format for Vagrant use. You can download basic base boxes from Vagrant website or you can create your own by packaging a VM/Vagrant instance. Vagrant supports installing boxes from both the local file systems and an HTTP URL.

I am using using Ubuntu 12.04 LTS (Precise Pangolin) 64 bit as my Vagrant base box. First I install a box

vagrant box add precise64 http://files.vagrantup.com/precise64.box

Once a base box is installed I can use it globally to the current Vagrant installation using box logical name (precise64 in this case).

Vagrant Instance

Once box is installed I can create a Vagrant instance by just typing

vagrant init precise64

Configuring Vagrant Instance

A Vagrant instance configuration is controlled by Vagrantfile (generated by vagrant init). All Vagrant configuration options are embedded in following block,

Port Forwarding

This option can be used multiple times to define more than one port mapping between host and guest. Using following, traffic sent to port 80/8000 on the host machine will be delivered to port 8080/8000 on the guest machine.

Shared Folders/Synced Folders/NFS

You can create a shared folder mapping between host and guest by adding shared folder option,

config.vm.share_folder "foo", "/guest/path", "/host/path"

where foo is logical name for the mapping. Required arguments are logical name, host path and guest path. Host path is relative to Vagrantfile. Additional option arguments can be passed when required.

Default sharing method and shared folder performance depends on VM type. For instance, a VirtualBox shared folder performance is inversely affected by number of files in the shared folder.

When run on Linux or Mac hosts, Vagrant can also share files to the guest via NFS. Unlike VirtualBox shared folder, for NFS shared folder performance does not degrade with increase in number of files in the shared folder. You can enable NFS sharing as

From version 2 Vagrant provides a more generic configuration synced_folder (share_folder is more VirtualBox specific).

The first parameter is a path to a directory on the host machine. If the path is relative, it is relative to the project root. The second parameter must be an absolute path of where to share the folder within the guest machine.

Starting Vagrant Instance

You can start a Vagrant instance by running following which will create a fully functional virtual machine.

vagrant up

Once virtual machine is up and running, using vagrant ssh will automatically drop you into a fully functional terminal shell to guest machine,

vagrant ssh
vagrant@precise64://vagrant$

To access the shared folder you can change directory to /vagrant. Normally I add cd /vagrant in .bashrc file of vagrant user on Vagrant VM which allows me drop directly into shared folder /vagrant on ssh.

Stopping Vagrant Instance

You can halt, suspend, reload or destroy a Vagrant instance.

Halting

vagrant halt provides a graceful shutdown of virtual machine. To resume working again run vagrant up.

Reloading

vagrant reload will quickly restart the virtual machine, apply any configuration change in Vagrantfile and run the provisioner (skipping the import sequence).

Suspending

vagrant suspend will save the current running state of your virtual machine and then stop it. To resume working again run vagrant resume.

Destroying

vagrant destroy will delete the complete virtual machine setup from the disk. To resume working again run vagrant up (full rebuild and import).

Specifying The Provisioner

Vagrant provisioners allows you to easily install softwares, packages, libraries and configure them. Vagrant supports various provisioners including Puppet and Chef. Puppet and Chef provisioners can be used both in solo/standalone mode as well server mode.

I prefer to use to Puppet as provisioner but based on your familiarity you can choose Chef or any other option. config.vm.provision method is used to enable provisioners as following.

Provisioner configuration details are provided using the using key-value options. In addition often a longer form is used to describe provisioner and configuration. For instance following longer form is

Provisioning Vagrant Instance

Once provisioner and related configuration details are specified, we can run provisioner using vagrant up or vagrant reload or vagrant provision. For already running virtual machine you can call either vagrant reload or vagrant provision. As explained above vagrant reload will apply both changes in Vagrantfile as well as provisioner configuration. Running vagrant provision will just apply changes in the provisioner configuration.