13. HANDS-ON TUTORIAL:  Automating Docker Swarm Configuration on Multiple Instances using Ansible

13. HANDS-ON TUTORIAL: Automating Docker Swarm Configuration on Multiple Instances using Ansible

Introducing automated configuration management

Introduction

Welcome to our blog post on using Ansible to install Docker on two EC2 instances. In this tutorial, we will be using a GitHub repository that contains the necessary Ansible files and configurations to set up our environment. We will begin by cloning the repository and navigating to the Ansible directory. From there, we will edit the inventory and tasks files to specify the necessary configurations for our manager and worker nodes.

We will then generate SSH keys on both the manager and worker nodes and add the worker's public key to the manager's authorized keys. Next, we will update the worker's hosts file to include the manager's IP address and add the manager's public key to the worker's authorized keys.

Finally, we will run the Ansible playbook and use the Docker stack deploy command to launch our project. By following these steps, you will have successfully installed Docker on two EC2 instances using Ansible. Let's dive in and get started!

Tools Utilised

  • Ubuntu

  • Ansible

  • SSH

  • Docker

  • Docker-Compose

  • Docker Swarm

  • Git

  • GitHub

  • Python

  • Flask

  • MySQL

  • NGINX

Step-by-Step Guide

Install Ansible on manager-node

1. Update the package index and upgrade all packages on the system.

sudo apt update && sudo apt upgrade -y

2. Install ansible

sudo apt install -y ansible

3. Verify your ansible install

ansible --version

Configure the Ansible files to match your system on manager-node

4. Download the code from the GitHub repository and go into the ansible folder

git clone https://github.com/mrbilalshafiq/DevOps-Project-2 && cd DevOps-Project-2/ansible

5. Update the IP addresses

vi inventory.yaml

You need to replace the <manager_node_ip> with your manager-node's public IP and the <worker_node_ip> with your worker-node's public IP address but don't include the '<' & '>' symbols.

all:
  children:
    manager:
      hosts:
        <manager_node_ip>:
    worker:
      hosts:
        <worker_node_ip>:
  vars:
    ansible_user: ubuntu
    ansible_ssh_private_key_file: "~/.ssh/id_rsa"
    ansible_ssh_common_args: "-o StrictHostKeyChecking=no"
    ansible_python_interpreter: "/usr/bin/python3"

6. Update the ~/DevOps-Project-2/ansible/roles/worker/tasks/main.yml file

vi roles/worker/tasks/main.yml

You need to replace the <manager_node_ip> in the value field of the join_token key with your manager-node's public IP but don't include the '<' & '>' symbols.

---
# tasks file for join_swarm
    - name: Add Worker to manager node
      docker_swarm:
        state: join
        advertise_addr: worker
        join_token: "{{ hostvars['<manager_node_ip>']['swarm_info']['swarm_facts']['JoinTokens']['Worker'] }}"
        remote_addrs: [ 'manager-node:2377' ]

Configure SSH Keys on manager-node

7. Generate SSH Keys

Generate a new ssh key pair and store them in the default location.

ssh-keygen

8. Give Ansible access to the manager-node

cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys

9. Copy manager-node's public SSH key

cat .ssh/id_rsa.pub

cat displays the file's contents. You must highlight and copy the contents.

Configure worker-node for Ansible

10. Add manager-node's public SSH key to ~/.ssh/authorized_keys in worker-node

vi ~/.ssh/authorized_keys

Press i to insert text then go to a new line and right-click to paste, if you're in Visual Studio Code, then enter esc and :wq!

Example:

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDS+7wTsrOBXILAWp0DLmcnqSXIdbovSqS/sJ+GjYj0ehjLFlZCx0R1qfoDKMPFf+eVbrdl4TvPtUyfSP1x9/n1yloYkKszsvL2JopN0Qg2CMgDEp3g7xzpBEwJDxpM33+D0CipEmri4NqFeksNTMqrwjniqlj/pyKHIJJtPpUhznOyaxcWHnsw4pVmyJFEWaqq8dkHnGsD2kFNlF2sUU4KJpWqKfFsvFQdnx8cu9/Mp4iA9sVGJQA3dSNO0+aUD0xB9sNJ6KuKqHaQC6UUShpdEzoNZ+Ftfq/BLAzQ81sbai/r5RbzlncltPHoStEbcN81yrWnkviclCW0UtfIk+Hr test-key
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCZX5G1o5dUSAA7KWaeU/6/2b4FR58RFFx//K7fTxi7rcqaSBV1Et0HywdgR/z46dnGW2XaY23Aj2axXKkckObLaWILLOLB8O0bSGClVrqN9zX0yXcxUZ5wA0BLlM5Vu+lqq3rhoiDkleMpuDMyRod7MD44wII3D05lvMe4xa8nVSKc2jwSMg+NpgYy9+dgBKR7k4lV2Ib1GR1RA0DJuoFew9ZBDdFpEMNk+6YagavdRrHCXxfrz6f21Gane7qBnKENuL3Vt2sECj8+oWR6xC/A/rd0LkWyvBG/rlzfrYLf9CA28vXV2Jr7YevQKExJSgFvJjCw9Wesl71Nj1qVQ4guRZwlOoDJUzN9BM9Gh65y5rcnTRmgU3yr5tWdwp9kwOSggUzUR78sZMqaphz+udDwUwFq0wSQ+Ikr0BSdMj+8VIXx3uf3Klh1n8XMIBdQD8wqOccYurGJIVDAzfIDjAavl4/66Zhm1hDC95h6qhcScxzPQQmwMUE68m21duK/srE= ubuntu@ip-172-31-82-30

11. Set the hostname and IP address for manager-node in the /etc/hosts file on worker-node

sudo vi /etc/hosts

Follow the format below:

<manager-node-ip> manager-node

# ALL THE BELOW LINES ARE ALREADY IN THE FILE
127.0.0.1 localhost

# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts

12. Generate SSH keys to store in manage-node which allows Ansible to connect to worker-node

ssh-keygen

13. Copy worker-node's public SSH key

cat .ssh/id_rsa.pub

cat displays the file's contents. You must highlight and copy the contents.

Example:

Final steps on manager-node

14. Add worker-node's public SSH key to ~/.ssh/authorized_keys

vi ~/.ssh/authorized_keys

Press i to insert text then go to a new line and right-click to paste, if you're in Visual Studio Code, then enter esc and :wq!

Example:

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDS+7wTsrOBXILAWp0DLmcnqSXIdbovSqS/sJ+GjYj0ehjLFlZCx0R1qfoDKMPFf+eVbrdl4TvPtUyfSP1x9/n1yloYkKszsvL2JopN0Qg2CMgDEp3g7xzpBEwJDxpM33+D0CipEmri4NqFeksNTMqrwjniqlj/pyKHIJJtPpUhznOyaxcWHnsw4pVmyJFEWaqq8dkHnGsD2kFNlF2sUU4KJpWqKfFsvFQdnx8cu9/Mp4iA9sVGJQA3dSNO0+aUD0xB9sNJ6KuKqHaQC6UUShpdEzoNZ+Ftfq/BLAzQ81sbai/r5RbzlncltPHoStEbcN81yrWnkviclCW0UtfIk+Hr test-key
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCZX5G1o5dUSAA7KWaeU/6/2b4FR58RFFx//K7fTxi7rcqaSBV1Et0HywdgR/z46dnGW2XaY23Aj2axXKkckObLaWILLOLB8O0bSGClVrqN9zX0yXcxUZ5wA0BLlM5Vu+lqq3rhoiDkleMpuDMyRod7MD44wII3D05lvMe4xa8nVSKc2jwSMg+NpgYy9+dgBKR7k4lV2Ib1GR1RA0DJuoFew9ZBDdFpEMNk+6YagavdRrHCXxfrz6f21Gane7qBnKENuL3Vt2sECj8+oWR6xC/A/rd0LkWyvBG/rlzfrYLf9CA28vXV2Jr7YevQKExJSgFvJjCw9Wesl71Nj1qVQ4guRZwlOoDJUzN9BM9Gh65y5rcnTRmgU3yr5tWdwp9kwOSggUzUR78sZMqaphz+udDwUwFq0wSQ+Ikr0BSdMj+8VIXx3uf3Klh1n8XMIBdQD8wqOccYurGJIVDAzfIDjAavl4/66Zhm1hDC95h6qhcScxzPQQmwMUE68m21duK/srE= ubuntu@ip-172-31-82-30
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC0XeBFWP58MXv8naZu6aDf2KRpBXdRUsvmHrMTg1oZMbNTEjY0PBqFDV6dIARVDV2waX+oeCD8XvUvoVtljnwbEVw3YqcJ3dermfX64cYWowXmsNuv2wbMLAKJq1reiDf6CsHou7NI6id5mJ5YJOkUkPiOqlCAnw+Cf7hJTCsrXaE8qLa0YLChnHewX9JflXcvBO6wmu93MxYbFOWJjr1Un0/1Zl5+7P/BJ3YqvOVbA/ZPFB5yNnvKdawD6MKRcuiFO/wYkpEOkOOmbd8PPIJHrmfGRIKTE7+n6qAinadSx4EdhHTnVCCj2NqK287+T2AUXSTSwKmzGPn13YEeaNcovC4qsjPTlTzJ1pN6wqGV4ETdp8Kq32sC0NtTWNyE0Ebc3Kj9N2VIf7WkogR7xKdwDYdqGfDphKPqKBxHnKMFQaSF2wMzsdp8X0gzIeiFHYTpdCISlyofYW9BxyovCs2YpbGk795DLKsSJSbA9bo9Hc9/oYLk5J0nwm5Cb+gUimc= ubuntu@ip-172-31-89-137

15. Run the Ansible Playbook

ansible-playbook -i inventory.yaml playbook.yaml

The inventory file is used to specify the hosts and groups of hosts that the playbook will run against, while the playbook file contains the instructions that Ansible will execute on those hosts.

16. Deploy the containers across the swarm

cd .. && sudo docker stack deploy --compose-file docker-compose.yaml Project2

17. Get the IP address of each instance

curl ifconfig.me

18. Access the application using both IPs

Conclusion

Ansible's ability to automate and manage multiple instances in parallel makes it an efficient tool for scaling and managing large-scale cloud deployments. Ansible also allows for easy integration with other IT operations and management tools, making it a valuable addition to a company's IT toolset.

Ansible is a powerful automation tool that can greatly benefit companies by simplifying and automating the configuration of instances in the cloud. It's a valuable tool that can help companies save time, and resources and improves the scalability, reliability and security of their cloud infrastructure.


Did you find this article valuable?

Support Bilal Shafiq by becoming a sponsor. Any amount is appreciated!