Atomic Object’s blog on everything we find fascinating.

Using Vagrant AWS with Capistrano

Vagrant 1.1 was recently released, adding support for virtualization providers other than VirtualBox. Among the providers now available is one for AWS. In switching my Vagrant workflow from VirtualBox to AWS, I ran into a problem; and in solving it, I discovered a better way to integrate Vagrant with Capistrano.

1. Vagrant Setup

Vagrant 1.1 was released recently. This release adds support for provider plugins, including a new, freely available provider for AWS. Rather than using VirtualBox on your local machine as the virtualization provider, you can now provision Vagrant-managed VMs in the cloud. This makes it much easier to try out things that require more resources like multi-VM environments and VMs requiring lots of RAM.

No Longer Distributed as a Gem

While Vagrant was initally distributed as a Ruby gem, Vagrant 1.0, introduced packages as the preferred installation method. Now with Vagrant 1.1+, it is no longer distributed as a gem. For more on why this change was made, see Mitchell’s blog.

1.1.x Installer Downloads Available at vagrantup.com.

To get Vagrant, download an installer from vagrantup.com. Once you’ve installed Vagrant, you can install the vagrant-aws provider: $ vagrant plugin install vagrant-aws

2. AWS Setup

Set up Account / Billing Info

To use the vagrant-aws provider, you’ll need an AWS account. If you don’t have one, you can set one up here.

Create an IAM User

You’ll probably also want to create an IAM user specificly for use with Vagrant. This allows you to limit access and revoke it if the account is compromised. You can find more info on IAM users and best practices for managing access to your AWS account here.

Keypair

Once you’ve crated an IAM user and downloaded the API keys, you’ll also want to generate a new SSH keypair from the EC2 management console. Name that ‘vagrant’, too, and save it to ~/.ssh/aws/vagrant.pem.

Security Group

Finally, you should also set up a separate Security Group to use with these VMs. You’ll need access to at least port 22 for SSH, though opening port 80 and 433 for HTTP(S) traffic might also be useful depending on your particular needs.

Vagrant Box Setup

We’ll assume we already have Ruby 1.9.3 and Bundler installed. We’ll also assume that we have an existing project laid out something like described above.

Let’s start by adding a dummy box to Vagrant that will let us work with the AWS provider. The new box format requires only that boxes contain a metadata.json file specifying which provider to use. Beyond that, the provider is free to require other files of its own. The Virtualbox provider’s box format includes VMDK disk images for example. The AWS provider does not require any disk images, but allows for the inclusion of a Vagrantfile specifying some default values. Here we can use the empty example box provided in the vagrant-aws project repo — we’ll specify all the values we need in our project’s Vagrantfile.

By using Vagrant’s ssh-config command, we can dynamically generate the config file our vagrant capistrano stage is based on. This allows us to point that stage at whatever host Vagrant has spun up for us at the time.

By taking advantage of vagrant ssh-config and the fact that Capistrano uses Net:SSH (which can parse ssh config files), we can make a dynamic stage pointing to any VM Vagrant is currently running.