Today we're going to configure web-server in a Docker container using Ansible. So first of all:-
What is Ansible?
Ansible is a software tool that provides simple but powerful automation for cross-platform computer support. It is primarily intended for IT professionals, who use it for application deployment, updates on workstations and servers, cloud provisioning, configuration management, intra-service orchestration, and nearly anything a systems administrator does on a weekly or daily basis. Ansible doesn't depend on agent software and has no additional security infrastructure, so it's easy to deploy.
Because Ansible is all about automation, it requires instructions to accomplish each job. With everything written down in simple script form, it's easy to do version control. The practical result of this is a major contribution to the "infrastructure as code" movement in IT: the idea that the maintenance of the server and client infrastructure can and should be treated the same as software development, with repositories of self-documenting, proven, and executable solutions capable of running an organization regardless of staff changes.
While Ansible may be at the forefront of automation, systems administration, and DevOps, it's also useful to everyday users. Ansible allows you to configure not just one computer, but potentially a whole network of computers at once, and using it requires no programming skills. Instructions written for Ansible are human-readable. Whether you're entirely new to computers or an expert, Ansible files are easy to understand.
Ansible Playbooks
Ansible Playbooks are used to execute scripts. The playbook is a *.yml file that says what to do when this script is called. An Ansible Playbook have a minimal structure consisting of:-
hosts — target group of hosts
tasks — a performed action or a role
Ansible Inventory
An Inventory is a file that describes the devices Ansible will connect to. Devices can be specified in the Inventory file using IP addresses or names. Devices can be specified one at a time or divided into groups.
So let's configure httpd docker container using ansible:-
Configure Docker in the managed node.
Start and enable Docker services.
Pull the httpd server image from the Docker Hub.
Run the httpd container and expose it to the public.
Copy the html code in target.
So we have a Master-node and Target-node. First, we install Ansible in the Master node, Ansible is written in python so we can simply install it using pip command.
pip3 install ansible
This will install the ansible in the system.
After the installation first, we need to set up the inventory where we can provide the IP of target node:-
vim ip.txt
Now give the path of inventory to the ansible configuration file, the ansible configuration file is not present by default so we have to create it:-
vim /etc/ansible/ansible.conf
Now we check the connectivity by using:-
ansible all -m ping
The ping is successful.
We can list these number of tasks in a yml file, also called Ansible Playbook such that Ansible can execute the yml and perform these steps itself. And you can run this playbook to install and configure an Apache web server on top of docker, on any number of hosts or target nodes.
We will breakdown the ansible code in a number of steps:-
Step 1: First we will write code to create docker repository from which host can download docker:-
- yum_repository:
name: "docker-ce"
description: "docker"
baseurl: "https://https://download.docker.com/linux/centos/7/x86_64/stable/"
gpgcheck=0
Step 2:
To configure yum repository so that we can install dependencies of docker if they are not present:- *This is just an optional step, there's a very little possibility that this dependency software is not installed in your RedHat. Make sure RedHat DVD is installed on your computer.
- file:
state: directory
path: "/dvd"
- mount:
src: "/dev/sr0"
path: "/dvd"
state: mounted
fstype: iso9660
- yum_repository:
name: "docker"
description: "docker repository"
baseurl: "https://download.docker.com/linux/centos/7/x86_64/stable/"
gpgcheck: no
- yum_repository:
name: "yum"
description: "main yum repository"
baseurl: "/dvd/AppStream"
name: "dvd1"
description: "appstream repository"
gpgcheck: no
- yum_repository:
name: "yum"
description: "main yum repository"
baseurl: "/dvd/BaseOS"
name: "dvd2"
description: "baseos repository"
gpgcheck: no
Step 3:
Now yum repository is configured, its time to install additional softwares needed by Docker to run on RedHat:- *This is just an optional step, there's a very little possibility that this dependency software is not installed in your RedHat. Make sure RedHat DVD is installed on your computer.
- package:
name: "libcgroup"
state: present
- package:
name: "container-selinux"
state: present
Step 4:
Now to install docker:-
- package:
name: "docker-ce-18.09.1-3.e17.x86_64"
state: present
Step 5:
Now start the Docker services:-
- service:
name: "docker"
state: started
enabled: yes
Step 6:
Ansible can't work on Docker in the Target node, so first, we have to install docker library for python in the Target-node:-
- pip:
name: "docker"
Step 7:
Now we can perform operations on the docker, so we pull the httpd image form the docker-hub:-
- docker_image:
name: httpd
source: pull
Step 8:
Now have to copy html code from Master-node to Target-node. First, we create the directory and then copy html code into it:-
- file :
name : "/var/www/html"
state : directory
- copy:
src: "/root/Ansible/home.html"
dest: "/var/www/html/"
Step 9:
Now create and launch the docker container and expose the ports:-
- docker_container:
name: webserver
image: httpd
state: started
exposed_ports: 80
volumes : "/var/www/html/:/usr/local/apache2/htdocs/"
published_ports: 9459:80
Step 10:
With the firewalld on, the host can't access the content, so we have to disable the firewalld or we can add the port number to the firewalld so it can allow access to the host on that port number:-
- firewalld:
port: 9459/tcp
permanent: yes
state: enabled
zone: public
At last, our ansible code is complete and it's time to run the playbook.
Ansible Playbook code:-
- hosts: all
tasks:
- file:
state: directory
path: "/dvd"
- mount:
src: "/dev/sr0"
path: "/dvd"
state: mounted
fstype: iso9660
- yum_repository:
name: "docker"
description: "docker repository"
baseurl: "https://download.docker.com/linux/centos/7/x86_64/stable/"
gpgcheck: no
- yum_repository:
name: "yum"
description: "main yum repository"
baseurl: "/dvd/AppStream"
name: "dvd1"
description: "appstream repository"
gpgcheck: no
- yum_repository:
name: "yum"
description: "main yum repository"
baseurl: "/dvd/BaseOS"
name: "dvd2"
description: "baseos repository"
gpgcheck: no
- package:
name: "libcgroup"
state: present
- package:
name: "container-selinux"
state: present
- package:
name: "docker-ce-18.09.1-3.el7"
state: present
- service:
name: "docker"
state: started
enabled: yes
- pip:
name: "docker"
- docker_image:
name: httpd
source: pull
- file :
name : "/var/www/html"
state : directory
- copy:
src: "/root/Ansible/home.html"
dest: "/var/www/html/"
- docker_container:
name: webserver
image: httpd
state: started
exposed_ports: 80
volumes : "/var/www/html/:/usr/local/apache2/htdocs/"
published_ports: 9459:80
- firewalld:
port: 9459/tcp
permanent: yes
state: enabled
zone: public
To run the ansible-playbook:-
ansible-playbook <playbook-name>.yml
As you can see there are no errors shown by the ansible. Now since our manage node, IP is 192.168.43.176 and the exposed port is 9459, also we moved an html file to the httpd server’s default serving directory (/usr/local/apache2/htdocs/) so let’s access it over a web browser and let’s see if our server is running or not!
So we can see, our Target-node is configured successfully and working fine.
All Research done here is under the guidance of Mr. Vimal Daga sir, so all thanks to Vimal sir for providing such information to us.