How Vagrant makes our lives easier
As a part of our DevOps mentality here at BigPanda, we believe in the ancient saying Automate All the Things™. We also believe that each developer should have a standalone offline available version of our applications to work on at any time (regardless of, say, commute connectivity problems). Instead of having each developer carry around a small data center in their backpack, we're using something we call a DevBox. The DevBox is a Vagrant box packed with goodies that are our basic infrastructure needs, such as redis, mongodb, rabbitmq and other stuff. Vagrant is a small layer of automation that wraps your favorite hypervisor/container, available as apt-get/brew or even a windows installer.
Vagrant makes it super easy to bring up one or many virtual machines, using a simple descriptive file called “Vagrantfile”:
# -*- mode: ruby -*- # vi: set ft=ruby : VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.box = "ubuntu13.04" config.vm.box_url = "http://cloud-images.ubuntu.com/vagrant/raring/current/raring-server-cloudimg-amd64-vagrant-disk1.box" config.vm.provider "virtualbox" do |v| v.memory = 2048 end config.vm.provision "ansible" do |ansible| ansible.playbook = "provisioning/devbox.yml" end config.vm.network :forwarded_port, host: 27017, guest: 27017 #mongodb config.vm.network :forwarded_port, host: 6379, guest: 6379 #redis #and it goes on... end
As you can see from the code above, you can easily define network connectivity between the virtual machines and the host, allowing, for example, port forwarding to expose services. More importantly, you can use a vast array of automation tools to configure the newly created virtual machine(s). And as we’ve written previously, we’re also using our beloved Ansible automation tool. Ansible ensures that the machine(s) are set up with all the software needed, configured to our production needs. All this using:
$ vagrant up #skadoosh Bringing machine 'default' up with 'virtualbox' provider... ==> default: Preparing network interfaces based on configuration... default: Adapter 1: nat ==> default: Forwarding ports... default: 27017 => 27017 (adapter 1) default: 6379 => 6379 (adapter 1) ==> default: Running provisioner: ansible... ______________________ < PLAY [Devbox Galore] > ---------------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || ... ... ... PLAY RECAP default : ok=38 changed=13 unreachable=0 failed=0
By using this simple Vagrant DevBox, we can:
- Eliminate (almost) entirely the Works On My Machine™ phenomenon, because the target operating system on the virtual machine matches our production machines, as opposed to our development laptops
- Take snapshots while troubleshooting to return to clean states (because the DevBox boils down to simple local virtual machines)
- Quickly bootstrap a new development environment, instead of the usual “takes a week to install the needed software”. The newly onboarded developer can start hacking in a matter of minutes.
- “Dog fooding” our Ansible playbooks, which are the same as used in production.
Because Vagrant is not limited to managing a single virtual machine, creating additional Vagrantfiles to test local clustering environments is just as easy, but let’s not dive into that. It’s material for a more comprehensive post, which we will publish soon.
Anyhuze, to summarize, use Vagrant, it rocks!