"Works on my machine!" – Developing and Testing Continuous Delivery with Vagrant
I still hear it often in teams, even in agile ones where unit tests, integration tests and continuous integration are integrated in daily work. One team member says it’s working and another with slightly different local environment says it’s not. Even more serious: local environments often don’t reflect the deployment environments, for example because the favorite Linux distribution of the developer is not the required server distribution or it just has slightly different configuration and software versions.
To solve these issues and for testing continuous deployments including provisioning I had an eye on Vagrant for a while. But with limited time I only tried small test installations until recently.
Our marketing department is quite technical compared to other companies, yet still using non-Linux OS for various reasons. To edit and test new content for our homepage the local compilation didn’t always work out as expected (tested and deployed on Linux by developers). Perfect testbed for a real world usage of Vagrant.
The goal: Editors just installing Vagrant, updating their repository and starting via vagrant:
git clone git://some.repository/path.git vagrant up
And everything is ready for usage in a started VM, first website already compiled and can be viewed by typing the VM’s IP into my local browser.
On way might be to prepare a VirtualBox image with everything preinstalled, but the disadvantage is I need to maintain the image with software updates, changes etc. manually. With Vagrant I tell it to use a basic small Debian or Ubuntu box which is downloaded from given URL and everything is provisioned via Puppet or Chef.
Preparation was a combination of a small Vagrantfile and provisioning via Puppet. My Vagrantfile:
Vagrant::Config.run do |config|. config.vm.box = "lucid32" config.vm.box_url = "http://files.vagrantup.com/lucid32.box" config.vm.boot_mode = :gui config.vm.network :hostonly, "192.168.33.10" config.vm.provision :puppet do |puppet| puppet.manifests_path = "puppet/manifests" puppet.module_path = "puppet/modules" puppet.manifest_file = "init.pp" end end
The rest is installed and prepared via puppet modules and manifests on first “vagrant up” which I provide in the projects repository in a puppet/ directory.
With the release of Vagrant 1.0 not long ago I think this has potential for a wider adoption of not only local setups of one or multiple VMs for development, but also to test more automation of various kinds for developers, testers, sysadmins -> DevOps. On the way to better Continuous Delivery.