Ansible

Overview

We have two categories of Ansible playbooks; installations and tasks. Installation playbooks follow a hierarchy to install and configure VMs in the correct order where tasks are used for one-off or repeating jobs that we need to run, e.g. running ETL processes or running database backups.

Our inventory

Installation

Tasks

Install Ansible on MacOS/Linux

Ansible is a Python so the easiest way to install it is using Pip;

$ sudo pip install ansible

Once it has installed it should be possible to run the following command from $TIS-DEVOPS

$ ansible jenkins -i ansible/inventory/build -m ping
10.1.0.4 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

Inventory

We use dynamic inventory with Ansible and the logic for the inventory is held in $TIS_DEVOPS/ansible/inventory.py, the other scripts in that directory call that file with the platform name. This reduces the amount of work required to setup a new platform and reduces the capacity to make mistakes when updating the inventory across the board.

There is also a test.py file that runs unit tests against inventory.py to help avoid making breaking changes.

Creating a new stack

  1. Check out $TIS-DEVOPS
  2. Create a new directory under ansible/roles/docker-compose/templates/:stack_name, these files are treated like Jinja2 templates so variables can be used throughout.
  3. Add a docker-compose.yml in that new directory. If your application needs environment variables then use an environment section, i.e.  

    environment:
      DATABASE_HOST: "{{ database['host'] }}"
  4. Create new playbook under ansible/ directory that matches your service name

  5. Add the hosts to the Ansible inventory file for platforms you are targeting.
  6. Commit and push your changes to Github.

  7. Create a deploy job in Jenkins by copying the 'revalidation-dev-deploy' job and changing the export STACK=revalidation to match your stack name.

Encrypted Content with Vault

We use Ansible Vault to encrypt sensitive settings in configuration files. The process for encrypting, decrypting and rekeying is well documented on the Ansible site so this section simply outlines how we are configuring it internally.

Our build server is configured to use a user called jenkins so we have added a password file in /etc/ansible/vault_password which is only readable by that user. We then configure Ansible to use that file for any encrypted setting files by using an /etc/ansible/ansible.cfg that looks like this; 

[defaults]
# some basic default values...
vault_password_file = /etc/ansible/vault_password	

When Jenkins runs any Ansible playbooks that contain encrypted content then Ansible will pick up the password automatically.