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’
- 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 │ ├── README.md │ ├── 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
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: git state: present - name: "Installing Nano using apk module" apk: name: nano state: 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.
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.
ansible_python_interpreter: python variable, was overriden 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
--- - 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 https://docs.ansible.com/ansible/latest/modules/docker_container_module.html
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 container docker 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-play state: 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:
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: