A Very Simple Vagrant Deployment

Last week, I looked at the getting a rails server pushed up to AWS using a Vagrant. After that was working, I decided I wanted to be able to test changes on a local VM, then push that VM to the cloud when I liked it, rather than test all my changes in the cloud.

In the directory where I had the Vagrantfile and the shared folder for the rails server, I did vagrant up --provider=virtualbox, and I got this:

An active machine was found with a different provider. Vagrant
currently allows each machine to be brought up with only a single
provider at a time. A future version will remove this limitation.
Until then, please destroy the existing machine to up with a new
provider.

Machine name: default
Active provider: aws
Requested provider: virtualbox

So apparently one of the choices is to vagrant destroy and then vagrant up with a different provider. Unfortunately, vagrant destroy will flag my VM in AWS as “terminated,” which means it will be deleted. So that would mean an operation that I intend only to change from “dev mode” to “deploy mode” in my personal workflow would actually delete a VM in the cloud. That sounds like a recipe for disaster.

Another choice is just to maintain a separate folder, so that I do my dev work, vagrant up, poke around on localhost, and when I’m happy I copy the application folder from my “virtualbox” Vagrant project to my AWS Vagrant project. This isn’t acceptable either, because one reason I am using Vagrant is to avoid having any manual file copy steps in my deployment.

It looks like there are a few workarounds, none of which make me super happy.

  1. I could define multiple machines, one for each provider, and then vary which machine I call vagrant up on. This would work, but I don’t like it because I’m using a feature that’s designed to let me spin up multiple different machines instead to spin up the same machine in multiple environments.
  2. I could have the config file check some environment variable to see which provider I currently care about. This seems like more work, and I already have enough environment variables to think about.

Also, mitchellh suggests option 1. So we’re going with option 1.

The first thing I did was just add these two lines to my Vagrantfile, after config.vm.box

  config.vm.define "dev"
  config.vm.define "aws"

Those are the only changes I made.

Then I did vagrant up dev --provision --provider=virtualbox. Vagrant dutifully went and found a version of the box I was using, for the virtualbox provider, and started downloading an image. (Side note: I work in coffee shops whenever I get the chance, but you may want to download vagrant box images on faster WiFi ahead of time.) That worked fine. I ssh’ed to the box with vagrant ssh dev and made a superficial change to the static pages app from the rails tutorial, so that I would be able to tell whether my changes worked. Then I halted the VM, and did vagrant up aws --provision --provider=aws. (Note that the first aws in that command is the name of a VM. The --provider=aws is what told Vagrant to spin this one up in the cloud.)

Actually, I ran vagrant up --provision --provider=aws && vagrant ssh aws and then got a drink of water, because I was going to be waiting for a minute. (Specifically, my Vagrantfile causes AWS to wait while the cheapest tier of VM compiles some Rails dependency from source, which takes a couple minutes.)

It worked! I was able to visit the VM in my browser and immediately see the change I had made. No manual file copy. No manual deployment work at all, besides bundle install and actually starting the web server.

I think, in retrospect, that the error message at the beginning of the post is too dire. I’d want it to say something like “You already launched the machine called ‘default’ with one provider. Vagrant associates machines with providers. You can add a line such as config.vm.define "dev" to your Vagrantfile, and associate that machine with a different provider.” The suggestion that I use vagrant destroy to handle this case seems like an over-reaction, and turned me off for a minute because I don’t like deleting things.

Anyway, that was the victory condition for this post. Till next time, happy learning!

-Will

Helpful Posts:

http://stackoverflow.com/q/17059982 https://gist.github.com/maxlinc/8c64c5e93734a3c939b8 https://github.com/mitchellh/vagrant/issues/2733

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s