A gentle introduction to Vagrant, the automated Virtual Machine builder

Tags: , ,

As a developer, you've probably heard about Vagrant, Docker, Chef and other VM and container tools. This series of articles will attempt to explain what these tools do and why you may want to investigate using them. At the end I'll provide you a few scenarios of how to work with these tools to set up consistent environments.

In this first article, we'll discuss Vagrant.

Vagrant – a VM Builder

Vagrant is a tool that provisions virtual machines in a scripted way, so that the machines can be rolled out to a team of developers, or as nodes of a cluster, with ease. Vagrant works with VirtualBox, VMWare, and even Microsoft HyperV, and you can write provisioning scripts in a special file, Vagrantfile, which uses Ruby, and use any of a number of plugins to make your life easier such as Chef, Berkshelf, and Librarian.

You can use Vagrant to share configuration scripts via a centralized repository, or embed a Vagrant configuration into the source code of your project to make it easy to set up the development environment.

Vagrant terminology

Vagrant uses boxes – essentially virtual machines pre-configured with software – as the starting unit of any configuration. You can find a ton of existing boxes at atlas.hashicorp.com – if one suits your needs exactly, you can use it directly. If it's close, you can create a new one based on it. You can also build your own boxes from scratch using Virtualbox.

Vagrant boxes go through two initialization stages – configuration, where the virtual machine is actually created, and provisioning, where software is installed and various network settings are applied.

The Vagrant team uses the command vagrant up to signify the starting up of a Vagrant box. Vagrant boxes are suspended or halted (a VM pause or shutdown) when you're finished using them. Finally, Vagrant boxes can be removed by using the destroy command.

You can bring in all sorts of tools to help you fetch the right software, including the extremely popular choice, Chef. Chef is another open source project that provides recipes, sets of instructions, to install software on a virtual machine. You can also install a dependency management tool, such as Berkshelf or Librarian, which allows you to create create and find cookbooks using versioning.

Vagrant – a quick start

First, download Vagrant from vagrantup.com. You'll want to make sure your machine can run typical virtual machine engines such as VirtualBox. This tutorial is geared for VirtualBox but you can also use VMWare or Microsoft Hyper-V (there is a $75 plugin to Vagrant to configure VMWare virtual machines).

Next, try the vagrant command from your OS prompt. You should get something looking like this:

$ vagrant
    Usage: vagrant [options] <command> [<args>]
        -v, --version                    Print the version and exit.
        -h, --help                       Print this help.
    Common commands:
         box             manages boxes: installation, removal, etc.
         connect         connect to a remotely shared Vagrant environment
         destroy         stops and deletes all traces of the vagrant machine
         global-status   outputs status Vagrant environments for this user
         halt            stops the vagrant machine
         help            shows the help for a subcommand
         init            initializes a new Vagrant environment by creating a Vagrantfile
         login           log in to HashiCorp's Atlas
         package         packages a running vagrant environment into a box
         plugin          manages plugins: install, uninstall, update, etc.
         provision       provisions the vagrant machine
         push            deploys code in this environment to a configured destination
         rdp             connects to machine via RDP
         reload          restarts vagrant machine, loads new Vagrantfile configuration
         resume          resume a suspended vagrant machine
         share           share your Vagrant environment with anyone in the world
         ssh             connects to machine via SSH
         ssh-config      outputs OpenSSH valid configuration to connect to the machine
         status          outputs status of the vagrant machine
         suspend         suspends the machine
         up              starts and provisions the vagrant environment
         version         prints current and latest Vagrant version
    For help on any individual command run `vagrant COMMAND -h`
    Additional subcommands are available, but are either more advanced
    or not commonly used. To see all subcommands, run the command
    `vagrant list-commands`.

Now you're ready to try configuring a virtual machine. Let's take a pre-fabricated machine from the organization's repository, HashiCorp, and configure an instance of it. How about Utopic Unicorn?

Downloading a Box

We can use the vagrant box command to download a box. Think of this as
a seed VM image, one that is copied when a vagrant is provisioned. These
boxes are stored in the home directory of the user under the
.vagrant.d folder.

To show your downloaded box images:

$ vagrant box list
bunchc/utopic-x64   (virtualbox, 0.2)
coreos-alpha        (virtualbox, 681.0.0)
hashicorp/precise64 (virtualbox, 1.1.0)

To download a box:

$ vagrant box add bunchc/utopic-x64
==> box: Loading metadata for box 'bunchc/utopic-x64'
    box: URL: https://atlas.hashicorp.com/bunchc/utopic-x64
This box can work with multiple providers! The providers that it
can work with are listed below. Please review the list and choose
the provider you will be working with.
1) virtualbox
2) vmware_desktop
Enter your choice: 1
==> box: Adding box 'bunchc/utopic-x64' (v0.2) for provider: virtualbox
    box: Downloading: https://atlas.hashicorp.com/bunchc/boxes/utopic-x64/versions/0.2/providers/virtualbox.box
==> box: Successfully added box 'bunchc/utopic-x64' (v0.2) for 'virtualbox'!

Setting up a Vagrant VM

Now let's set up a new Vagrant and use the bunchc/utopic-x64 image as
our base box. First, create a directory, then use the vagrant init
command to set up the Vagrantfile configuration file:

$ mkdir devbox
$ cd devbox
$ vagrant init --provider virtualbox
    A `Vagrantfile` has been placed in this directory. You are now
    ready to `vagrant up` your first virtual environment! Please read
    the comments in the Vagrantfile as well as documentation on
    `vagrantup.com` for more information on using Vagrant.

Note – although you can use the vagrant box command from the previous section to pre-load a VM Box image, you don't have to. You can just start here and Vagrant will download the box anyway.

We should configure the base box for this machine, as the default is
base, a bare-bones machine with very little to offer us. Edit the
Vagrant file and change the config.vm.box line to match our fetched

config.vm.box = "bunchc/utopic-x64"

Booting our Vagrant

Now, let's boot the server:

    $ vagrant up --provider virtualbox

Vagrant spins up a virtual machine using the box image – you can give it a hint if you have more than one VM engine installed – for example vagrant up --provider virtualbox or vagrant up --provider vmware_workstation. The default is virtualbox if you leave the --provider flag out of your vagrant up command.

Once the machine is up and running, you can connect to it as the vagrant user:

    $ vagrant ssh

The Vagrant user you'll connect to is usually named vagrant with a password of vagrant, but that isn't actually required. In fact, Vagrant creates and signs special SSH keys between your host machine and the box, so that you don't have to enter passwords to work in the command line. Your user traditionally is granted sudo rights, so a simple su – is all you need to get in as Root.

Boxes Usually Need Provisioning

You'll only get so far with a this box. Beyond starting it, you'll want to load software. But stop… Think about what you're about to do.

If you load software by using SSH to connect and then using apt-get
directly, you'll be modifying the Vagrant instance without a way to
re-create it. Also, if you tweak settings in VirtualBox or VMWare on the
box, you'll be doing the same thing for the configuration.

How can we keep our settings and distribute them to other developers? We
do this via the Vagrantfile using the various provisioning methods.

You can automate the install of MySQL, Postgres, Apache, nginx, whatever you need to use to do your work. There are several built-in ways to provision, from directly copying and manipulating files to executing shell commands. For example, to copy a VIM editor config file into your machine you can add the following fragment to your Vagrantfile:

config.vm.provision "file", source: "./.vimrc", destination: "/etc/vimrc"

You can execute shell commands, so you can do things like:

config.vm.provision "shell", inline: "yum update"

By default, you're doing these things as the root user, so you can do any kind of long-form provisioning you want. Just remember to suppress responses from questions where you can so that the process can execute in a fully automated way.

Networking – routing to the outside

You can forward a port on the virtual machine directly to a local port on your host computer, all from your Vagrant file. For example, to forward port 80 of your box to port 8080 on the host, add:

config.vm.network "forwarded_port", guest: 80, host: 8080

Now, http://localhost:8080 will browse to a server running on the Vagrant on port 80. This sure beats the ssh -L or ssh -R commands.

There are a lot more networking features you can enable, such as host-only or bridged networking. You can read about these features and others in the Vagrant Docs.

Next steps

In my next article, I'll show you how we can use the Chef provisioning tool to automate setting up software packages, and introduce you to Berkshelf, a Chef recipe management tool that can make life easier for you as you start configuring more complex Vagrants.