Linux and PHP web application support and development (Bromsgrove, UK)

Ansible – System configuration management and orchestration

With the increasing prevalence of virtual machines, cloud servers and so on, performing systems administration is becoming more time consuming (more servers = more work!).

One approach at solving this has been through the use of system management tools like puppet, cfengine and chef. In our case, when we’ve looked at these in the past, they appear to require addition daemons installing and often a funky new language/syntax to learn.

A few weeks ago we came across Ansible, which operates over SSH, doesn’t have significant dependencies (probably just python-apt and python-json for Debian Squeeze) and fits in well with how we work.

Below is an introduction to ansible, along with some examples of use.


I installed ansible for Debian Squeeze via an Ubuntu PPA – using the following in my /etc/apt/sources.list file :

deb lucid main

Then, apt-get install ansible

By default, ansible expects it’s configuration to be in /etc/ansible. The hosts file is used to lists and group servers we care about – e.g.



My First ansible command

A simple example, which tries to ping all known hosts is :

$ ansible all -m ping -u root

This causes ansible to use it’s ‘ping’ module, telling it to run on ‘all’ hosts. When connecting to the servers we will try and login as the ‘root’ user.

We could also just do this on one host –

$ ansible -m ping -u root

which will output something like : | success >> {
    "changed": false, 
    "ping": "pong"

Or just to our database servers, using ‘ansible my-databases -m ping -u root’ and so on.

Doing something useful (modifying an .ini file)

A more interesting example, which changes the PHP config file on the selected servers could look like :

$ ansible -m ini_file -a "dest=/etc/php5/apache2/php.ini section=PHP option=error_log value=/var/log/php.log backup=yes" -u root

This :

  • Operates on the group ‘my-webservers’ (see above hosts file)
  • Uses the ‘ini_file’ module
  • Modifies /etc/php5/apache2/php.ini on the remote server
  • If there is a change, copies the original to a file (like /etc/php5/apache2/php.ini.2013-05-20@10:15~)
  • Look for an error_log key in the PHP section and make sure it’s set to /var/log/php.log

If ansible doesn’t need to change the file (perhaps error_log = /var/log/php.log is already in the file) then you’ll see output like : | success >> {
"changed": false,
"dest": "/etc/php5/apache2/php.ini",
"group": "root",
"mode": "0644",
"msg": "OK",
"owner": "root",
"size": 65821,
"state": "file"

If on the otherhand, a change is needed, then you’ll see something like : | success >> {
"changed": true,
"dest": "/etc/php5/apache2/php.ini",
"group": "root",
"mode": "0644",
"msg": "OK",
"owner": "root",
"size": 4187,
"state": "file"

My only complaint with the above, is that ansible strips out comments from the config file (if it deems it necessary to make a change).

It’s great that ansible can do this – but really we want to store commands in some sort of batch file (aka playbook) so we end up with a nicely documented build – and as servers are added to a specific pool, they will end up receiving the same configuration. Playbooks can reference multiple playbooks through use of the include line.

Obviously ansible can do far more than mentioned above – like creating files based on a template, changing file permissions, installing specific packages (yum, apt) ….. the modules documentation is a good place to start.

, , , , ,

One thought on “Ansible – System configuration management and orchestration

Leave a Reply

Your email address will not be published. Required fields are marked *