Let’s Launch Docker using Ansible.

Ravi Malvia
5 min readDec 17, 2022
Docker and Ansible

Ansible is a configuration management tool. It has the ability to configure more than one system at a time. This tool helps to automate cloud provisioning, application deployment, ad-hoc task execution, network automation, and multi-node orchestration. Ansible makes complex changes, like zero-downtime rolling updates with load balancers easy.

Ansible has two types of nodes:

  1. Controller Node
  2. Managed Node

The controller node, which has Ansible software installed, and the other nodes that are controlled by the controller node are called managed nodes.

How the Ansible Control the other nodes?

So first, let’s talk about how other tools, like Chef and Puppet, do this configuration management. Let’s take one tool Chef.

When the system that has Chef installed, works as a controller node sends packets that contain instructions, to the other nodes. The other node or managed nodes need an extra package or program which can read the instruction, this program is called Agent. This Agent is the one who applies your configurations on remote Linux, macOS, Windows, and cloud-based systems.

Ansible leverages the power of SSH, or Secure Shell, which is a network communication protocol that enables two computers to communicate. Ansible doesn’t require an agent program to be installed on managed nodes to configure them. that’s why Ansible called the Agentless program.

Prerequisite for the setup:

✔ Since we have used AWS EC2 services, you should have an AWS account and know how to launch an instance.

✔ You should have a basic understanding and command knowledge of Docker.

Installation of Ansible:

There are two methods of ansible installation:

  1. Using YUM:

a.) Install the Epel repository for extra packages:

# sudo yum install epel-release -y

# sudo yum install ansible -y

When you use yum to install Ansible. it creates a folder /etc/ansible , Here is the inventory file /etc/ansible/hostsand ansible configuration file /etc/ansble/ansible.cfg are located.

2. Using PIP:

# pip install ansible

When you install Ansible using pip, it won’t create this folder /etc/ansible . Ansible works fine from any directory. You can choose any folder like create /ansiblews folder and in this folder generate a sample ansible.cfg file and create an inventory file /ansiblews/hosts you can use the below command.

# ansible-config init --disabled -t all > ansible.cfg

when you run the above command, ansible.cfg will be created, there you can change your inventory file default location

# (pathlist) Comma separated list of Ansible inventory sources
inventory=/ansiblews/hosts

We have successfully set up an Ansible Controller Node.

Let’s write the inventories in the inventory file /ansiblews/hosts. We have two inventories named m_node1 and m_node2. Since we are using AWS instances, the user is ec2-user.

[m_node1]
43.205.110.192 ansible_user=ec2-user

[m_node2]
3.108.228.129 ansible_user=ec2-user

When you connect to another instance or local systems, you always need a username and password to access but in this case, the nodes are located on the AWS cloud So we need to have access to its private key.

To import the private key from your local system to your controller node, we can use putty to login to your controller node locally and paste the private key there because putty allows you to copy and paste from a local system to its connected system. and store it in your controller node. I have saved this key in one of my folder /ansiblews/cloud.key . Add this key address to your inventory file /ansiblews/hosts.

[m_node1]
43.205.110.192 ansible_user=ec2-user ansible_ssh_private_key_file=/ansiblews/cloud.key

[m_node2]
3.108.228.129 ansible_user=ec2-user ansible_ssh_private_key_file=/ansiblews/cloud.key

So now inventories are also added. Let’s check if it is connected to managed nodes.

# ansible all -m ping

Output:

Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
43.205.110.192 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
yes
3.108.228.129 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}

The above message shows that it’s a success.

When you install any package without a root user or root privilege, Normally, it doesn’t allow it. So if you want Ansible to be able to configure other managed nodes So you have to give Ansible some root privileges, or Ansible has to pretend to be a root user by becoming one for other managed nodes. Do the below setup, and we are good to go.

[root@ip-172–31–1–6 ansiblews]# vim ansible.cfg

[privilege_escalation]

# (boolean) Toggles the use of privilege escalation, allowing you to 'become' another user after login.
become=true

# (boolean) Toggle to prompt for privilege escalation password.
become_ask_pass=False

# (string) Privilege escalation method to use when `become` is enabled.
become_method=sudo

# (string) The user your login/remote user 'becomes' when using privilege escalation, most systems will use 'root' when no user is specified.
become_user=root

Let’s write a playbook to launch a Docker container on managed nodes.

[root@ip-172–31–1–6 ansiblews]# vim docker_deploy.yml

---
- name: docker Container web-server
hosts: all
tasks:
- name: docker import repository
ansible.builtin.yum_repository:
name: docker-ce
description: this is docker repository
baseurl: https://download.docker.com/linux/centos/$releasever/$basearch/stable
enabled: 1
gpgcheck: 1
gpgkey: https://download.docker.com/linux/rhel/gpg


- name: docker install
ansible.builtin.yum:
name:
- docker-ce
- docker-ce-cli
- containerd.io
- docker-compose-plugin

- name: start service docker
ansible.builtin.service:
name: docker
state: started
enabled: true

- name: Install python3 as depedencies
yum:
name:
- python
- pip

- name: install docker-py python module
pip:
name: docker-py


- name: launch docker container
docker_container:
name: my_server1
image: httpd
state: started
volumes:
- /ansiblews/:/var/www/html/
expose:
- 8081

Let’s execute this playbook

[root@ip-172–31–1–6 ansiblews]# ansible-playbook docker_deploy.yml

Output:

TASK [Gathering Facts] *****************************************************************************
ok: [43.205.110.192]
ok: [3.108.228.129]

TASK [docker import repository] ********************************************************************
ok: [3.108.228.129]
ok: [43.205.110.192]

TASK [docker install] ******************************************************************************
ok: [43.205.110.192]
ok: [3.108.228.129]

TASK [start service docker] ************************************************************************
ok: [3.108.228.129]
ok: [43.205.110.192]

TASK [Install python3 as depedencies] **************************************************************
ok: [43.205.110.192]
ok: [3.108.228.129]

TASK [install docker-py python module] *************************************************************
ok: [43.205.110.192]
ok: [3.108.228.129]

TASK [launch docker container] *********************************************************************
changed: [43.205.110.192]
changed: [3.108.228.129]

PLAY RECAP *****************************************************************************************
3.108.228.129 : ok=7 changed=1 unreachable=0 failed=0 skipped=0 rescued= 0 ignored=0
43.205.110.192 : ok=7 changed=1 unreachable=0 failed=0 skipped=0 rescued= 0 ignored=0

That’s wonderful; we have launched Docker container successfully.

Thanks for reading.

And if you come this far, please give some claps as the token of your appreciation. If you have any problem understanding it kindly can connect to me on my Linkedin .

--

--

Ravi Malvia

I'm a DevOps engineer and machine learning enthusiast with a passion for exploring the unknown depths of tech.