Every time I start working on new project it takes me a significant amount of time to get up and running. You have to install all software dependencies, make sure they are located in the right place. Configure environment variables. Hope and pray that whatever requires compilation will compile correctly on my Mac version, with the version of GCC that I happen to have installed. I've lost many a day with these types of problems once again here at LogicBlox. This is a problem we [started to tackle at Cloud9](https://openshift.redhat.com/community/blogs/solving-the-two-week-problem-by-developing-in-the-cloud) by standardizing the runtime environment (an OpenShift gear), but we had not yet gotten to tackling the automatic installation of all dependencies when I was there. What we did do was offer an Amazon AMI for new employees, that they could instantiate and connect to Cloud9 to get up and running quickly. However, running such VMs is costly and we hadn't yet built tooling to manage this process.
Today somebody pointed me to [Vagrant](http://www.vagrantup.com), a system to "Create and configure lightweight, reproducible, and portable development environments". Rather than putting your entire development environment "in the cloud", it essentially creates a small personal cloud based on VirtualBox instances, locally on your machine. I've been playing with it a little bit today and it works very nicely.
The idea is to create a declarative configuration file (using a Ruby DSL in a file called `Vagrantfile`) of what you need of your environment:
Vagrant::Config.run do |config| config.vm.box = "lucid32" config.vm.forward_port 80, 4567 config.vm.customize ["modifyvm", :id, "--memory", 1024]
config.vm.provision :chef_solo do |chef| chef.recipe_url = "http://server.com/cb.tar.gz" chef.add_recipe("dev_env") end end
This examples uses [Chef](http://www.opscode.com/chef/), but you may as well use another deployment system, or even a shell script to provision the VM. After creating this file, you run `vagrant up` and it builds a VirtualBox VM with the specified environment, and maps `/vagrant` in the VM to the directory containing your application and `Vagrantfile`. You can SSH into the VM with `vagrant ssh` if you like and you can destroy the VM with `vagrant destroy`. If you make changes to your `Vagrantfile`, you run `vagrant reload` to rebuild the VM.
The brilliance of this approach, in my opinion is:
1. Instead of manually `apt-get`ing, or `.pkg`-installing your way toward your ideal development environment, you now have a single file that specifies _everything_ that needs to be done to setup such an environment. 2. There is no valuable state in the VM, all your source code is stored outside the VM and simply mapped into the VM. Anything you would like to keep, you put in `/vagrant`. 2. A `Vagrantfile` is environment independent, you can commit it to your repo, and others, whether they are on Mac, Windows or Linux can fully reproduce the environment with a simple `vagrant up` to get up and running. 3. The VirtualBox VMs that Vagrant produces are throw away VMs. You can destroy them at any time, so they don't need to take up disk space and memory. Whenever you need to run it again, you just `vagrant up` and you're ready to go.
I think this is a _very_ powerful idea and it gets even more interesting once you start to reuse these specifications to setup production deployments "in the cloud".