Vagrant

User Story:

  • As a sysadmin
    • I want to provision virtual machines quickly and in a repeatable fashion
    • so that I can setup test clusters in development and easily share these with others

As a sysadmin, I’m a big fan of simplicity of the libvirt ecosystem. Installing and configuring KVM and libvirt is a straightforward experience, and when learning the API, it’s nice to know that knowledge will extend beyond the next release cycle, product licensing change or corportate buyout. Using vm-builder (topic for another post) makes provisioning simple guests fast, efficient and flexible with a ton of automated configuration options.

On the dev side, provisioning Virtual machines for testing and development have always been a bit of a pain. Creating multiple images for devs and customizing all their settings can be a tedious process, it can be slow to physically get the VMs to the devs, and multiple variations either take a bunch of handholding or multiple images and lots more disk space. Of course, libvirt is an option on workstations also, it’s nice and simple to install these days thanks to brew, but still requires a decent amount of configuration, especially in a dev environment when things Should Just Work™.

Enter Vagrant

Vagrant is a ruby gem which performs automated building and provisioning of VirtualBox machines. Vagrant takes care of all the behind the scenes work with VirtualBox, so while you need VirtualBox installed, you technically never even need to launch the app.

So what? Double clicking an app doesn’t take much time, and I get to use a nice GUI.

A ha, this is where the awesomeness begins. To see why vagrant is so awesome, here’s a simple example of getting up and running (I’ve trimmed a bit of the verbosity from the responses, but this is honestly it:

[~/dev/vagrant-demo]$ gem install vagrant
Successfully installed vagrant-0.8.2
[~/dev/vagrant-demo]$ vagrant box add lucid64 http://files.vagrantup.com/lucid64.box
[vagrant] Downloading box: http://files.vagrantup.com/lucid64.box
[vagrant] Verifying box...
[~/dev/vagrant-demo]$ vagrant init lucid64
      create  Vagrantfile
[~/dev/vagrant-demo]$ vagrant up
[default] Importing base box 'lucid64'...
[default] Forwarding ports...
[default] -- ssh: 22 => 2222 (adapter 1)
[default] VM booted and ready for use!
[default] Mounting shared folders...
[default] -- v-root: /vagrant
[~/dev/vagrant-demo]$ vagrant ssh
Welcome to the Ubuntu Server!
vagrant@lucid64:~$ cat /etc/issue
Ubuntu 10.04.3 LTS \n \l

So what’s actually going on there? Basically, the lucid64.box is a preconfigured template, containing a base install of ubuntu 10.04, a pre-defined vagrant user and some tools for open box. When initializing the machine, vagrant creates a Vagrantfile which is a simple ruby configuration script. How simple you ask? It doesn’t get much simpler than this:

Vagrant::Config.run do |config|
  config.vm.box = "lucid64"
end

Of course, simple doesn’t mean it’s lacking in ability – there’s a [whole host of configuration options] you can specify from simple [ram] and [disk] customization to [auto provisioning] with chef, puppet or even simple bash scripts. Here’s an example with a few more options thrown in:

Vagrant::Config.run do |config|
  config.vm.box = "lucid64"
  config.vm.memory_size = 4096
  config.vm.host_name = 'awesome'
  config.vm.network "33.33.33.105"
end

What about when you’re done? you can simply power off the VM, suspend it, or destroy it, deleting its disks

There really is a ton of customization you can run on these things, so before I get too carried away, I’ll suggest you check out the [docs] and see for yourself.

What about security? Who made this “box” file?

I hear you, but fear not. For those who want to build their own boxes, not only is this possible, but with a tool called veewee, @patrickdebois has made is insanely easy. I’ll cover that in a followup post, but rest assured, this is Not a Problem™.

But wait, there’s more

You can have more than one VM in a Vagrantfile and when assigned IPs, such as in the example above, these hosts can communicate over a private, host-only network. This paves the way for setting up whole stacks / clusters on a single host, bringing dev/test-like-prod nirvana just one step closer.

Sharing the love

While I’ve worked on ops-only teams before, for the last three years I’ve been the ops guy on a team of devs. This changed two months ago when the formidable @fak3r joined us and now once again, ops is a team. When I was the sole ops guy, I become used to rolling hosts out with chef and so I’ve been blissfully in my own little world of ‘self-documenting’ ops code, however it turns out that while the code and builds with chef are self-documenting, chef itself isn’t, nor are the (many) legacy hosts that still exist in our cluster and some of the tools I’ve been using and taking for granted. Bringing on another team member always makes you re-evaluate how well documented things are. To complicate matters, at the same time as growing the team, we inherited a rather large second infrastructure to manage and consolidate into our existing infrastructure. On top of that, we’ve both just started working with the amazing RC team up at Harvard, so we’re both learning their infrastructure as well. Needless to say, documenting multiple new environments plus multiple legacy environments has proven challenging.

One of the awesome things about a new team member coming on board is always the new knowledge and perspectives they bring with them, new ways of looking at and solving problems and new tools and tricks to bring to the table. Before coming on board, @faker and I worked together on a few projects and had various ways of sharing info, from email and IM to Dropbox shared folders to google docs, google hangouts and wikis. By far the most useful way however, was when we would work on a problem and it would result in a blog post. This way, not only did we have the solution documented for the next time we needed quick access to it, but if anyone else had a similar problem, a short time googling might bring them to our solution. Whether it was something as simple as finding out that a university in the UK was the culprit in DoS'ing one of our sites, or rebooting XenServer machines on the command line or something as complex as solving global syncing problems for our huge datasets, the value of having other users input as well as being able to go back at any point and be reminded of the solution was obvious. It’s been way too long between posts here and I’m hoping to continue the tradition @fak3r started and get posts happening way more frequently up here. In this spirit, my next post will be on the awesomeness that is vagrant.