Saturday, March 28, 2015

Why I chose ansible for deployment

With our last project at work, I decided to switch to Ansible as our deployment tool.  So far I am super happy with how it works.  The main points from my (development team centric) point of view are:
  • the playbook for detailing how to deploy our application is nice, clean, and straight forward
  • the declarative syntax nicely separates the "what" from the "how"
  • since the playbook assumes only a fresh OS install with an ssh key, the playbook details every step of the install
  • the playbook itself serves as development documentation of what is on the boxes
I follow the general conventions of Twelve-Factor Apps, so I wrote the playbook with the goal of QA, integration testing, and production all being installed using the exact same playbook installing the exact same versions of software.  Just like in a Twelve-Factor App itself, you do this by using variables.

For our local usage, I wrote a simple script that you only have to tell three things:
  1. what product you want to install
  2. what version of the product you want to install
  3. what environment you want to install that product into
The environment is really just the name of an inventory file, so QA and Operations are welcome to create new environments without requiring any changes to the code base or even a new build of the code.

The install script does a few simple steps:
  1. auto updates itself
  2. downloads the correct version of the playbook, notes, and samples for the product
  3. show the user any installation notes for the product and exit, but only if the notes changed
  4. runs the playbook for the product with the correct inventory for the environment, passing any extra parameters to the ansible-playbook command
For each new product we create in development, I write a playbook that that product along with a nice set of installation notes that detail what variables are used in the playbook and what purpose they serve.  I also supply a sample inventory that shows a typical install's inventory.  

This means that installing a new app or upgrading an existing app are all the same thing, you run the install tool with the three standard parameters.  If there are new notes for this version, you are shown the notes and get a chance to react to those notes before you run the command again.  If there are no new notes, it just does the install/upgrade.

Due to the power of ansible, that install can be run in check mode to see what will change, or verify that the last install is still correct.  The inventory can contain tags that are used at install time to limit the install to only a few machines to allow for rolling upgrades.

Since the environment is defined by an inventory file, it is super simple to run ad-hoc commands on all the machines for an environment using the ansible command.