Setting up Ansible with pip-tools & tox

What you’ll need:

This demo is being executed on an Ubuntu 16.04 system.

What we are doing:

I like using tox and pip-tools to setup my Ansible working environment since it allows me to install Ansible consistently and reliably. Tox allows me to manage my virtualenvs letting me install just the packages I need to execute Ansible and nothing extra. pip-tools lets me generate a requirement.txt file that is used by tox to install the required Ansible packages into my virtualenv.

Demo:

Lets begin by cloning a sample repo. This is my standard starting repo, including some extra things like dynamic inventory scripts. These can be ignored for this demo.

The structure is as follows:

├── ansible.cfg
├── ec2.ini
├── ec2.py
├── group_vars
├── host_vars
├── playbooks
├── README.md
├── requirements.in
├── requirements.txt
├── roles
└── tox.ini

This probably looks familiar to those who are used to working with Ansible, but what might be different is the tox.ini and requirements.in files. I use these files with tox and pip-tools to setup my Ansible environment.

To get started, ensure that a requirements.in file exists and that we have defined our version of Ansible to install. We use this file as an input to pip-compile to generate a requirements.txt file which we can use to install the necessary packages for Ansible. The requirements.txt file defines the python package versions required for our application.

$ pip-compile requirements.in

Now that we have a requirements.txt file we can create our virtualenv using tox. Tox manages virtualenv and lets us install python packages in isolation. I prefer to work inside of virtualenvs since they are isolated which allows me to keep my global environment clean.

From the root of our project run:

$ tox
$ source .tox/py27-ansible2.3.0/bin/activate

Now that we have activated our virtualenv we should have Anisble installed and will be able to execute Ansible commands. Remember that our Ansible version is defined in our requirements.in file. Lets confirm that our environment is setup correctly by executing the following:

$ ansible --version
  ansible 2.3.0.0

Suppose we wanted to change the version of Ansible we were using. Perhaps we wanted to test an newer version, or ensure things work on an older version. we could just update the version in requirements.in and update the name of the virtualenv in tox.

change the version in the requirements.in

ansible==2.2.0

update the name of the virtualenv in tox.ini

[tox]
envlist = py{27}-ansible{2.2.0}
skipsdist = true

[testenv]
passenv = *
deps =
    -rrequirements.txt

$ pip-compile -r requirements.in
$ tox
$ source .tox/py27-ansible2.2.0/bin/activate
$ ansible --version
  ansible 2.2.0.0

This allows us to run Ansible 2.2.0 in one virtualenv, switch to the other, and use Ansible 2.3.0 without fussing with versions installed globally.

I Hope this is helpful, please feel free to contact me with any comments or suggestions.