Monday, October 3, 2016

Ansible experiment aka a review of my time using Ansible for building our deployment pipeline (part 1)

I have been playing around with Ansible and using it as a foray for Continuous Deployment. Few things I have read about Ansible is true:
  1. It's easy to read and get started on. Within minutes you can get a playbook started and someone else picking up on your work can definitely understand what you were trying to achieve.
  2. There is a minimum of requirements that you need, just a Ansible and whatever that it needs.
These are the few reasons why I like Ansible. After scratching my head for one or two days I pretty much wrote from scratch what I needed to perform my deployment script for our Django project. It was all very fast and painless.  You can say easy Ansible things are always easy to do. Some of these things are package installation, config management via templates etc.  These operations are a breeze and if your deployment only consists of these kinds of operations you will be thinking that Ansible is the best thing since sliced bread.

However hard things to do in Ansible turn out to be exceedingly hard to do, for example getting "psql" commands to idempotent turns out to be something really unwieldy such as this:

It can work, I have tried the answer, but then it still looks pretty much like a workaround to me.  Another thing that bugged me to no end is the fact that Ansible's test suites are so damn weak. I can appreciate the loftier goals of Ansible integration testing and would really appreciate if they can shoe implementation examples of these goals,  I am using Docker to build the test part of my playbook and at the end of the build I use a very simple selenium test using phantomjs to run a few tests like logging in and verifying that certain elements of our Django site is there and that will in the end give an assurance that the deployment is successful and the script is usable. Serverspec is there to ensure that services are configured correctly for example services are enabled during boot and configuration files are treated correctly.

Also, something practical that we do everyday like getting the deployment script to support two distributions (RedHat and Ubuntu in our case) can very much make your hitherto simple playbook grow and become this unwieldy monster. Our scripts for deployment is here:


This approach's weakness is however painfully obvious:

  • A huge toolchain. Everything needs to be installed and running by the numbers to achieve a green build. I really would rather just have an Ansible based integration test or a task that runs at the end to ensure that the site has been installed and running correctly. 
  • The build just takes too long, and more often than not strange problems occur which we are at a loss to explain. Debugging problems remotely on Travis sucks big time.
  • The command to run our playbook is overly complex now. 
 I have been thinking of a better way to do this and to make our script more dependable and run in half the time. I  know at this stage what I am saying sounds more like venting and ranty but then that is where the "Part 1" of this entry is all about. I will formalize what I say in concrete examples in the next few parts. While I might not like everything single thing I see about Ansible now, there are more positives than negatives that makes me still sitting in their camp.