Installing Docker using an Ansible Playbook on Ubuntu

For each server we manage with Ansible, we have stated that we have a 'common' selection of software that we always want to install. This can and likely will be different for everyone, but it's likely that there is some software you always want available, right from the get go.

After this, however, everything is custom.

Not every server needs a web server, a database, PHP, or NodeJS.

A huge win for me, and a big reason I like and use Ansible is Ansible Galaxy. Most programming languages have a central repo of good stuff. PHP has packagist, Elixir has Hex, JavaScript has NPM. Ansible Galaxy is basically this for Ansible roles.

Ansible Galaxy is really useful, even if you don't use Ansible. You can learn a lot about how to install X, Y, and / or Z by reading through one or more roles for the piece of software you want to install. And they are typically chock full of best practices.

Now I don't have a scientific, well constructed reason for my choice of roles. I typically look at the vanity metrics (download count, stars, 'score', watchers, that kind of thing), and then make a short list of roles to check out from there. There's nothing I can teach you here other than it's likely very similar to how you already use packagist, hex, or NPM.

In the case of our Rancher 2 Kubernetes nodes, we will always need to have Docker installed.

At the time of writing / recording, Rancher is only supporting Docker 17.03.2 on Ubuntu 16.04 (64-bit).

This version of Docker is not the latest and greatest. It's also a bit of a pain to get installed on to Ubuntu 18.x, without a bunch of additional commands.

Fortunately, Ansible will take care of all the hard work for us. We just need a role, and a bit of config.

Installing Roles From Ansible Galaxy When Using Docker

We could create our own role to install and manage Docker. But the whole point of a tool like Ansible is to leverage the power of the community, and the expertise within.

I will start by pulling in geerlingguy.docker. If you stick around in the world of Ansible for any length of time you will undoubtedly come across one of it's biggest proponents, Jeff Geerling. Jeff is an awesome dude, and we have a lot to thank him for.

Before we can use the geerlingguy.docker role, we need to pull this role down from Ansible Galaxy.

As we're using Docker, this is slightly more involved than the usual approach of just running ansible-galaxy install geerlingguy.docker.

We need a way for Docker to save the downloaded role to our local computer. And we need to think about where, on our local computer, we want to store the roles.

I'm going to start by tackling the second problem: where to store the roles we download?

This is a simple one for me. I'm going to put all roles into the roles directory. This is why I suggested using the codereviewvideos. prefix for our common role in the previous tutorial. This way it's obvious which are our own roles, and which are third party roles.

In order to pull the role down we will need an addition [to our ansible.cfg file][6]:

host_key_checking = false
roles_path = /crv-ansible/roles 

become = True
become_method = sudo
become_user = root

And a rather long winded Docker command:

docker run --rm \
        -v $(CURDIR):/crv-ansible \
        -w /crv-ansible \
        williamyeh/ansible:alpine3 \
        ansible-galaxy install geerlingguy.docker

You could become a total hipster and add this to your Makefile:

    @docker run --rm \
        -v $(CURDIR):/crv-ansible \
        -w /crv-ansible \
        williamyeh/ansible:alpine3 \
        ansible-galaxy install $(role)

And you can then make install_role role=geerlingguy.docker. Depending on how many roles you are installing, which can be a few when first setting up, this can be a nice little shortcut.

make install_role role=geerlingguy.docker

- downloading role 'docker', owned by geerlingguy
- downloading role from
- extracting geerlingguy.docker to /crv-ansible/roles/geerlingguy.docker
- geerlingguy.docker (2.5.2) was installed successfully


You Don't Need Those Roles

As a quick tip, if you're keeping your Ansible config under git (and you should) then you don't really need to commit most of the roles/ directory contents.

Here's the .gitignore file I use to only commit my own roles, and ignore any third party roles:


The first line tells git to ignore everything in the roles directory.

The second line negates the rule for any subdirectory of roles starting with codereviewvideos*, in other words codereviewvideos.whatever will work.

And the third line tells git not to ignore everything in those subdirectories.

It works for me.

Installing Docker Using Ansible

We have the required role now which takes care of most of the hard work for us.

All that remains is to specify exactly which version of Docker we want, and to add the role to our list of roles that our playbook will use.

I am going to add the following config to /group_vars/rancher-2-kubernetes-node:

docker_package: "docker-ce=17.03.2~ce-0~ubuntu-xenial"

This piece of config is a bit of a nightmare, and there are several open PR's / issues regarding this that will have hopefully been resolved soon.

Don't forget to add the role to your rancher-2-kubernetes-node.yml playbook:

- name: Rancher 2 Kubernetes Nodes
  hosts: rancher-2-kubernetes-nodes
     - codereviewvideos.common
     - geerlingguy.docker

Anyway, before we run the playbook, it's worth checking the remote server:

docker -v
-bash: docker: command not found

Then run the playbook:

make run_playbook

Assuming everything completes ok:

docker -v
Docker version 17.03.2-ce, build f5ec1e2

Pretty cool. And a lot easier than doing all this by hand.

There is an unfortunate caveat to this, however, which will become evident when we add firewall configuration in a few videos time.

In this video we covered how to install a very specific version of Docker, on a remote server, using Ansible.

In the next video we will learn how to create and manage Users.