2016-05-03

Overview

Vagrant allows you to easily manage and control multiple virtual machines. It is built on top of VirtualBox and VMWare, and it provides many exciting capabilities. You can create isolated development environments, experiment with new products and technologies, install new versions of existing packages, create your own private data center on your laptop, and run different operating systems. All that is available in an easy-to-manage and totally safe silo that can't interfere with your main activities and operating system.

In this tutorial, I'll show you how to set up Vagrant and start exploring the wealth of opportunities it affords.

Vagrant recently added support for Docker containers too, but I will not discuss that in this tutorial.

Installation

Download the free VirtualBox for your operating system from the VirtualBox website.

After download, just run the binary and install it.

Download Vagrant.

Again, just run the binary to install it.

Initializing Vagrant

Vagrant is a command-line based tool. Once installation is complete, open a console window and create a new directory called 'vagrant_intro'.

This will be your working directory from now on. Inside the vagrant_intro directory, type:

vagrant init ubuntu/trusty64

You should see the following text:

The generated 'Vagrantfile' is a Ruby file that controls your [one or more] virtual machines. It is a pretty big file with lots of commented out options. I will go over the important ones later, but let's give it a try first. Type: vagrant up.

This will cause Vagrant to download a prepared virtual box with the 64-bit Ubuntu 14.04 (trusty) release. It will take a while (several minutes) and spit a lot of text to your screen. While Vagrant is churning, let's talk about what a VM is in practical terms.

One view (which I usually adopt) is that the VM simulates a remote server. You should only communicate with it over its network interface. This is particularly useful for testing distributed systems where you shouldn't take advantage of any special VM-host interfaces because they will not be available on your production systems. When operating in this mode, you will normally communicate with your VM over SSH (possibly with a tool like Ansible).

Another view, which is also totally correct and valid, is to think of the VM as another OS running on your local machine. This view is useful if you want to develop directly on your target OS.

For example, a very common setup is to have developers write their code on a Mac using Mac OS X, but deploy to a Linux production environment. If you want to make sure that the code you develop on the Mac runs properly on Linux without having to deploy to a remote server, you can take advantage of synced folders where you read and write files on the host OS (typically Mac OS X) and have them immediately available on the guest OS (typically Linux).

This drops the "deploy" step from the edit-deploy-test cycle when working with remote systems. It also removes the need for an expansive staging environment that is a shared resource and needs to be managed carefully across all developers. With a local VM, nobody is going to break your environment, and you can experiment as much as you want without worrying about breaking someone else's code.

You can, of course, use both synced folders and still SSH into your VM. There are other options that blur the borders such as port mapping.

The Vagrantfile

Here is a stripped-down version of the Vagrantfile with some of the most important options:

The syntax is Ruby, which gives you a lot of flexibility if you want to add conditionals and loops. This is particularly helpful if you use your Vagrantfile to manage a cluster of virtual machines.

Connecting to Your VM

You can connect to your running VM by typing: vagrant ssh.

This will launch an SSH session and let you fiddle with your VM interactively.

Once inside your VM, you can pretty much do anything you want: run commands, create users, create files and directories, etc. You are logged in as the 'vagrant' user, which has sudo privileges, so you have full control over the VM.

Exchanging Data With Your VM

Vagrant automatically maps the folder on the host machine that contains the Vagrantfile to the /vagrant directory inside the guest machine. This lets you edit files in your favorite editor on the host machine and have it available in the guest or alternatively have the guest write some output file to the /vagrant directory and browse the synced folder on the host.

Mapping Guest Ports

Often you'll want to run some application that communicates through a port. The most common one is a web server. Vagrant allows you to forward guest ports to the host machine.

For example, in the configuration above, the guest port 80 is mapped to the host 8080 port. What that means is that whatever service is running on port 80 in the guest can be accessed as localhost:8080 on the host machine.

Let's see a demonstration. First, I'll put a simple index.html file in the ~/vagrant_intro directory on the host that is synced with the /vagrant_data directory on the guest.

Then, after I SSH into the guest machine, I'll run a little web server in the /vagrant_data dir:

This one-liner Python HTTP server simply serves any static file in its working directory. Now, since port 80 is mapped to the host's 8080 port, you can browse to localhost:8080 and view the result of running the server.

Connecting to the VM Through the Network

You can also connect to the VM through its IP address as if it's a really separate server. I always add a hostname to /etc/hosts so I don't have to use the naked IP address and because the code I'm testing is usually configured with the hostname of a production system. This is what you need to add to your /etc/hosts file:

Now, any network access to "production.server.com" on your machine will be sent to your VM.

In this case, the programs that usually connect to the remote server are configured with the VM IP address or hostname. Prior to Vagrant 1.7, there was a single private key that could be used for all machines. This was a serious security problem when people exposed their virtual machine over public networks and anyone could SSH in and get root access. Starting with version 1.7, Vagrant generates a fresh key pair for each machine. To find out where the private key for your machine is, run this command: vagrant ssh-config.

Here is how you can SSH directly to the VM:

Managing Your Virtual Boxes

Vagrant provides many commands to manage boxes. Let's explore. To see a list of commands, type: vagrant.

I covered some of the most common commands earlier. The box commands allow you to manage your boxes directly. For example, to see all the VMs on your machine, type vagrant box list. You can update boxes to the latest version with update. The reload command is very useful if you change your Vagrantfile. Finally, provision lets you provision, configure and install software on your VM using various provisioners including Chef, Puppet, Salt, my favorite Ansible, and even Docker.

Conclusion

Vagrant gives you an easy-to-use computer within computer. You can manage a fleet of VMs for diverse purposes, and the Vagrantfile is your interface for specifying how the VM should behave. Have fun exploring Vagrant. I just scratched the surface here.

Show more