Running Ansible Inside Docker

Phil Misiowiec
Feb 4, 2016 · 3 min read

At Healthcare Blocks, we use Ansible and Docker to build, deploy, and run customer application environments on top of Amazon Web Services. By convention, Ansible is normally installed right on top of the operating system layer. This post discusses an alternate strategy of deploying Ansible inside a standalone Docker image, which can then be used to control other machines and containers. This approach brings numerous benefits to operational, testing, and continuous integration processes.

Ansible — in contrast to other configuration management frameworks — does not require the installation of any agents within managed environments. Instead, commands are pushed over SSH and interpreted by a Python runtime. This simple, yet efficient model enables new environments to be spun up faster and greatly reduces the amount of dependencies required on the target machine in order for it to be configured by Ansible.

The environment where Ansible is installed — the “control machine” — is not as simple, however, to setup. It requires specific Python libraries, their system dependencies, and the tuning of configuration settings. As new Ansible modules are added or improved, other dependencies might be required.

Ansible is also a fast paced open source project with over a thousand contributors. Evaluating a recent release or working from the development branch can be quite the adventure and often involves toggling between specific Git repo tags or commits, which might, in turn, require rolling back a dependency too.

In a development environment, Ansible “playbooks” can be tested within a virtual machine using tools such as Vagrant and VirtualBox. Ideally, we want to start with a fresh environment state when running a new playbook. But the process of (re)creating a pristine testing sandbox is tedious with these tools.

So to sum up so far, we’ve got issues with dependency management, challenges when evaluating newer versions of Ansible, and an inefficient testing flow. Docker, anyone?

By creating an Ansible Docker image, like this one, we isolate all of the required dependencies, instead of thrashing around the host machine’s operating system and potentially breaking things in other areas. The Dockerfile declares a specific entrypoint, enabling a running container to function as a self-contained executable. In other words, it is a proxy to the ansible-playbook command.

docker run --rm -it -v $(pwd):/ansible/playbooks \
philm/ansible_playbook site.yml

Evaluating different versions of Ansible and tweaking its configuration changes is much simpler with Docker. Modifying the Dockerfile and rebuilding the image is significantly faster than other alternatives. Using Docker tags, I can easily reference older variants. And by setting defaults for several environment variables recognized by Ansible, I can override them at runtime, if necessary.

docker run --rm -it -v $(pwd):/ansible/playbooks \
philm/ansible_playbook site.yml

Testing Ansible playbooks in a pristine sandbox that can be recreated quickly during each test run can be handled by Docker, as an alternative to Vagrant. It requires building a VM-like Docker image that exposes an SSH service, such as this one and running the container:

docker run -d -p 2222:22 --name ansible_test \
-v ~/.ssh/ \

An example playbook command might look like this:

docker run --rm -it \ 
--link ansible_target \
-v ~/.ssh/id_rsa:/root/.ssh/id_rsa \
-v ~/.ssh/ \
-v $(pwd):/ansible/playbooks \
philm/ansible_playbook tests.yml -i inventory

Notice the linking of the two containers. Docker will automatically update /etc/hosts in the ansible_playbook container with the ansible_test container’s IP address. This allows your Ansible inventory file to be as simple as:


“I hate typing long commands…”

You can easily wrap the above commands into a bash script or makefile, but Docker Compose is also a great option. A sample docker-compose.yml is included in the repo. An abbreviated command is now possible:

docker-compose run --rm test tests.yml -i inventory

And anytime you want to reset the test environment, remove the ansible_target container before running the Docker Compose command.

docker rm -v -f ansible_target

Docker Images:

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store