With the advent of Docker and containerization in general, tools like Ansible, Puppet, or Chef have been losing weight as most of the configuration of the system occurs inside a container.Moreover, as cloud computing platforms like Google Cloud or AWS, or Azure, are providing managed Kubernetes clusters, the necessity of configuring machines is lower every day.
But, what happens if you cannot afford a cloud service and just want to buy a VPS or a dedicated machine and install Docker and Docker Compose to just run a couple of containers?
Should you do it by hand?
Not at all. Ansible to the rescue.
In this article, I will explain to you how to install, configure, and use Ansible to install Docker.
How to install Ansible
Installing Ansible consists of installing some CLI tools, and it’s very easy, regardless of the platform you are using. I will teach you how to install Ansible in Mac and Ubuntu.
For Mac users: you can install Ansible using Homebrew, just by running the following command:
brew install ansible
For Ubuntu users: you can install Ansible running the following commands:
sudo apt update
sudo apt install software-properties-common
sudo add-apt-repository --yes --update ppa:ansible/ansible
sudo apt install ansible
You can find more information in the official documentation.
Configuring Ansible is a quite simple operation.
First of all, you need to create a directory called playbooks. This is where you will store YAML files with the steps needed to configure your remote host -the VPS where you want to install Docker and Docker Compose using Ansible.Next, you need to create a file called inventory -it can be called whatever actually-, with the following content:
IP_OF_THE_VPS
That’s all. Pretty simple. The only thing to consider is that you need to be able to SSH this machine using an SSH key. So if ssh user@IP_OF_THE_VPS is already working for you, you are ready to execute Ansible playbooks.
A Playbook to install Docker and Docker Compose
This is the whole playbook YAML content, and I will explain step by step:
---
- hosts: all
remote_user: ubuntu
become: true
tasks:
- name: install dependencies
apt:
name: "{{item}}"
state: present
update_cache: yes
loop:
- apt-transport-https
- ca-certificates
- curl
- gnupg-agent
- software-properties-common
- name: add GPG key
apt_key:
url: //download.docker.com/linux/ubuntu/gpg
state: present
- name: add docker repository to apt
apt_repository:
repo: deb //download.docker.com/linux/ubuntu bionic stable
state: present
- name: install docker
apt:
name: "{{item}}"
state: latest
update_cache: yes
loop:
- docker-ce
- docker-ce-cli
- containerd.io
- name: check docker is active
service:
name: docker
state: started
enabled: yes
- name: Ensure group "docker" exists
ansible.builtin.group:
name: docker
state: present
- name: adding ubuntu to docker group
user:
name: ubuntu
groups: docker
append: yes
- name: Install docker-compose
get_url:
url: //github.com/docker/compose/releases/download/1.29.2/docker-compose-Linux-x86_64
dest: /usr/local/bin/docker-compose
mode: 'u+x,g+x'
- name: Change file ownership, group and permissions
ansible.builtin.file:
path: /usr/local/bin/docker-compose
owner: ubuntu
group: ubuntu
First things first, the hosts key, which value is all, means that the playbook is going to be executed over all the inventory hosts available. As we only have one, we can just set all and things will go just fine.
Then, we have the remote_user key: this is the user we use to SSH to the machine, let’s say ubuntu, but it could we whatever user with SSH access and proper permissions.
become: this means that we are going to execute the different commands using sudo. This is needed to install packages, change permissions, groups, etc. If you open Docker official documentation, you will find all of the commands are run as sudo.
Next, you find an array of tasks, which contains the different processes we are going to run over the remote host.Any task has a name, an action -like apt, service, or ansible.builtin.group, and optionally a loop. And the actions use to have params, like name or state in the apt one.
The first task, called install dependencies, installs the following packages:
-
apt-transport-https
-
ca-certificates
-
curl
-
gnupg-agent
-
software-properties-common
You can check in the documentation of Docker that these dependencies are required to install Docker.
If you look at the task, you will see that the state has the value present. This means that Ansible is going to ensure that these packages are present in the machine, so it will install only if needed -this is how Ansible is idempotent.
Next task, add GPG key, adds an APT key to the system. If you are familiar with Ubuntu, you’ll already know this is need to install certain repositories.
And just below we have the task add docker repository to apt, which is pretty obvious. It installs the repository of Docker in the machine.
Time to install Docker needed packages in the next task. More precisely, we are going to install the following:
Then, with the task check docker is active, we are going to ensure that the service is running after installation. And we check docker group is in place with the task Ensure group docker exists.
At this point, we should already have Docker installed in our machine. But we would be only able to run commands using sudo, which is not desirable. So we run the next task adding ubuntu to docker group, which basically adds the user ubuntu -our running user- to the group docker.
Now Docker is already installed and we can execute commands without sudo. But we don’t have Docker Compose, which is also needed to do what we want. The next couple of tasks install it.
The first one downloads the binary from the server and installs it under /usr/local/bin/docker-compose, providing the needed permissions.
The last one just adds the binary to the user ubuntu property.
Now we have understood the playbook, how could we execute it?
How to execute a playbook file using Ansible
Ansible comes with a CLI tool to execute playbooks, which is ansible-playbook.
Run the following command:
ansible-playbook -i inventory playbooks/main.yaml
And that’s all. Ansible should be able to connect and install all the needed stuff. The output will inform you of what kind of actions have run.
You can check that Ansible is actually idempotent by running again the command. Nothing should be changed.
Ansible is still with us
Regardless of the advent of Docker and the kind, there are still some tasks you should run over the machines, and you don’t want to do it by hand.
Ansible is still with us and can help you to provision machines in a repeatable, versioned way.This article was originally published .