Provision docker containers with Ansible

This post is a repost of the original (by me) available at

This is post serves as a reference to create a base for your next Docker project that might use your already in place ansible playbooks and roles.

Also sometimes setting up Docker to create fully configured containers based on extensive shell scripts and others at the Dockerfile level might become unmanagable. So just because Docker is awesome, and trendy these days, doesn’t mean you need to leave ansible getting dust.


> Ansible is a great companion to Docker

>The github url to the code presented here is available at the end of this post.

Ok, enough talk, ‘gimme the code’


* ansible

* ansible-galaxy

* Docker

* Docker-py ( pip install docker-py )

Creating a ansible role to test docker

So first let’s make use of the ansible-galaxy to scaffold our role instead of creating all the files by hand.

ansible-galaxy init docker-role

And let’s create a playbook.yml, a destroy.yml and inventory.yml file as well

touch playbook.yml destroy.yml inventory.yml

Ok so now we have our default ansible role directory and our created files

It should look like this

├── destroy.yml├── docker-role│ ├── defaults│ │ └── main.yml│ ├── files│ ├── handlers│ │ └── main.yml│ ├── meta│ │ └── main.yml│ ├──│ ├── tasks│ │ └── main.yml│ ├── templates│ ├── tests│ │ ├── inventory│ │ └── test.yml│ └── vars│ └── main.yml├── inventory.yml└── playbook.yml

So for now our role isn’t doing much, let’s add a few tasks to our `docker-role/tasks/main.yml`

Since we will be using an alpine based container let’s install a few apk packages in our main tasks file.

# main.yml
# tasks file for docker-role- name: “Installing git using apk module”apk:name: gitstate: present- name: “Installing Nano using apk module”apk:name: nanostate: present

And that should do it, as the purpose of this post is to demonstrate how to use ansible to provision docker containers, without using ssh containers, but docker-cli (abstracted by ansible ) to interact with the containers.

Defining an ansible inventory with docker

So now let’s define our `inventory.yml` file with our `yet to be created` containers.


all:  hosts:    example-play:      ansible_connection: docker      ansible_python_interpreter: python


The important part of our inventory file, which could also have been defined as an ini file, is our vars regarding the connection to the host.

So the `example-play` will be name of our created container, and the variable `ansible_connection: docker ` defines the driver that ansible will use to connect to the host.

Regarding the ansible_python_interpreter: python variable, was overridden from /usr/bin/python default value that ansible uses to refer to the python interpreter path, to `python` as we will be using the image `python:alpine` to create our container, and python is not available under the default path ansible searches.

Creating a playbook to create our docker container

So now that we have our docker compatible inventory file, let’s edit our playbook.yml file.

- name: Create our container
hosts: localhost tasks: - docker_container: name: example-play image: python:alpine command: [“sleep”, “1d”]- name: Example play hosts: example-play roles: - name: “docker-role”

The first part of our playbook, creates the container based on the `python:alpine` image and sets our container to run the `sleep 1d` command on the run directive, so that the container doesn’t enter on the python interpreter when it goes up.

Ansible docker_container vars at

The second part, targets our hosts defined at the example-play in our `inventory.yml` file, but this host is actually being created in the same playbook.

And finally will run our example role `docker-role` against that container.

So now we can run our playbook that we will create and run the role in it by running the following command:

ansible-playbook -i inventory.yml playbook.yml

Since ansible is all about idempotence, you may run the above command as many times as you wan’t and no changes should happen, meaning it won’t be creating the container more than once.

It will also name the container example-play when it creates it.

So if you want to enter your container at any time, you may run the docker cli command to interact directly with the container.


#The command below will run a python interpreter shell inside the containerdocker exec -it example-play python

Destroying our inventory when done

Ok, so since we will be creating containers to be provisioned with ansible, it’s also a good idea to have a way to remove our docker inventory.

Let’s edit our destroy.yml with the following contents.

- hosts: localhost
tasks:- docker_container:name: example-playstate: absent

This is similar to our playbook.yml creation part, except for the state of the container we wish to have. The state `absent ` is the same as stopped and removed.

To remove our container just run:

ansible-playbook destroy.yml

And that’s it for this post, thanks for reading, and hope you found it helpful.

Link to the github repository with the contents of this post:

Andre Ilhicas Santos

Written by

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