Configuration Management

Development Principles

using Ansible examples

Created by Will Thames / @willthames

About this presentation

This presentation is available on Github Pages at:

All code samples are included in the same repo, under examples

To save you having to remember that, I've published the info at

About me

I build the future!

  • 18 months with Suncorp
  • 8 years before that at Betfair in the UK

† see Devops, what's missing, what's next

About Ansible

  • Been around 18 months (first commit 23/02/2012)
  • Daemon-less orchestration and config management tool - runs over ssh and uses existing privileges
  • Requires python (rather than ruby)
  • Recently raised US$6m in funding for their ansibleworks business, which offers enterprise features
  • Doesn't need root! (except to do things that need root)

About Ansible

  • Assumes homogeneity (little abstraction of resources like package installation etc.). This is realistic within corporations, but reduces reuse
  • Task driven rather than convergence driven - much less declarative than chef, let alone puppet

And vagrant...

  • Vagrant is a tool to programatically manage virtual machines
  • The demos in this presentation rely upon Vagrant.
  • Vagrant supports Ansible as a provisioning method
Vagrant.configure(2) do |config|

  config.vm.define :shop do |shop| = "centos64-64" :private_network, ip: "" :forwarded_port, guest: 22, host: 2202

  config.vm.define :acct do |acct| = "centos64-64" :private_network, ip: "" :forwarded_port, guest: 22, host: 2203

  config.vm.provision :ansible do |ansible|
    ansible.playbook = "provisioning/playbook.yml"
    ansible.inventory_file = "provisioning/ansible_hosts"
    ansible.sudo = true

- hosts: vagrant

  - name: add dummy host in /etc/hosts
    action: lineinfile state=present \

  - name: ensure /usr/local is writable by admin group
    action: file state=directory group=admin mode=775 \

Getting started with Ansible

Install from OS package (yum, apt-get etc) or

git clone
pip install paramiko PyYAML jinja2
mkdir ~/.ansible
source ansible/hacking/env-setup -q

Setup Ansible config

cat > ~/.ansible/config << EOT
hostfile = ~/.ansible/hosts
library = ~/src/ansible/library

Talk to a target host

  • ssh-keygen (use a strong passphrase)
  • ssh-add (so you don't have to type your passphrase every connection)
  • ssh-copy-id $target (or OS equivalent)
ansible -m command -a date web | success | rc=0 >>
Sun Aug 25 14:41:08 EST 2013

This presentation is about Ansible

The principles are applicable to:

Chef, Puppet, Salt, Cfengine


Example environment

We'll use this environment for discussion purposes

The naive approaches

  • Snowflake servers!
  • ssh in a for loop running a bash script on each server
  • version controlled per-server configuration

Configuration management

to the rescue?


What can we improve?

  • All that copy and paste! Refactoring...
  • Modular playbooks
  • Hierarchical configuration
  • Repeatability
  • Security


Most configuration management frameworks have a way to have playbooks that include other playbooks.

Ansible recently introduced Role Dependencies, so that playbooks can include roles which can include other roles

This means that e.g. installing java or logstash can be separated out to roles

Hierarchical configuration

Configuration is typically multi-dimensional:

  • environment specific
  • application specific

Also, there are typically groupings of targets - e.g. dev environments and prod-like environments

Hierarchical configuration

Here there are likely elements common to the dev environment such as mail gateways, log shipping destinations, log level.

There are also likely elements common to application type, such as files to log ship, JVM versions etc.


There are two key elements to repeatability:

  • invariance: The system should not change between runs of the same playbook, no matter how long apart
  • idempotency: Running the same playbook twice should have no additional effects

This means that playbooks that install the latest version of an artifact, or checkout HEAD from version control are not repeatable.

Checks should be made when adding things - e.g. lines to a config file to ensure that it doesn't happen again on a second run

Version control is not just for

application code

It's probably obvious that you should commit your playbooks to source control.

But you also need to manage versions. So that you can run playbook v1.2 against dev, v1.1 against test and v1.0 against prod as improvements flow through the pipeline.

There are many ways to achieve this, but cheap branching (typically DVCS) is an easy way - whether that's a dev branch or just pointing dev at the 1.2 branch.


What you don't want is your production database passwords, or Amazon private keys, or any other sensitive data written in plain text in source control.

Typically a solution is for the target nodes to have decryption keys and then the configuration management software decrypting it as it writes the config file

ansible-vault is still a work in progress.

Software development practices


Unlike chef-cucumber and rspec-puppet, there are no common frameworks yet available. Using vagrant to test your changes in a throwaway VM will work in some cases.

Static Analysis

Again, puppet has puppet-lint, chef has food-critic.

Announcing ansible-lint!!

I've created an extensible lint for ansible at

$ bin/ansible-lint examples/example.yml
[ANSIBLE0001] Old style (${var}) brackets
    action: command echo ${oldskool}

[ANSIBLE0004] Checkouts must contain explicit version
    action: git a=b c=d


What about the devops?

  • Developers can work with ops on playbooks that work in dev environments through to production - shared ownership
  • Operations can provide playbooks that setup and configure monitoring, log shipping - all devs have to do is set the right variables
  • Depending on environment (e.g. devs typically won't have root privileges, ops won't know how best to deploy a particular application) collaboration will be essential - talk to each other!

What about the devops...

Dev and Ops relaxed and happy


Room for improvement

  • Testing framework
  • Sensitive data management
  • Community playbooks - or even the abstractions to allow reuse


Where Ansible excels

  • Trivial to get going
  • Great for orchestration (even if you use chef or puppet, it's nice to have something to tell servers to update themselves!)
  • Improvements to core are happening rapidly - more modules, more modularity

Useful links


Photo credits: Peta Thames