Module 5: Case Study - Ansible
Problem Statement: You are a DevOps Engineer and the organization you are working on needs to set up two configuration management server groups. One for Apache, another for NGINX. Being a DevOps Engineer it is your task to deal with this configuration management issue.
Let us see the tasks that you need to perform using Ansible:
- Create two server groups. One for Apache and another for NGINX
- Push two html files with their server information
Make sure that you donβt forget to start the services once the installation is done. Also send post installation messages for both the server groups.
Using Ansible roles accomplish the above tasks. Also, once the Apache server configuration is done you need to install Java on that server group using Ansible role in a Playbook.
I will reuse the Ansible roles from Assignment 4 β Ansible and the EC2 instances that were created in Assignment 1 β Ansible. %%SSH agent%%
EC2 instances
Ansible Control Machine
10.0.1.223
Slave110.0.1.65
Slave210.0.1.233
Create HTML Files:
- I prepare two
index.html
files, one for Apache and the other for Nginx, with the respective server information.
ubuntu@ip-10-0-1-223:~$ tree nginx_role/
nginx_role/
βββ README.md
βββ defaults
β βββ main.yml
βββ files
β βββ index.html
βββ handlers
β βββ main.yml
βββ meta
β βββ main.yml
βββ tasks
β βββ main.yml
βββ tests
β βββ inventory
β βββ test.yml
βββ vars
βββ main.yml
7 directories, 9 files
ubuntu@ip-10-0-1-223:~$ cat nginx_role/files/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ansible Deployment</title>
</head>
<body>
<div class="header">
<h1>Deployed from Ansible to Nginx</h1>
</div>
</body>
</html>
ubuntu@ip-10-0-1-223:~$ tree apache_role/
apache_role/
βββ README.md
βββ defaults
β βββ main.yml
βββ files
β βββ index.html
βββ handlers
β βββ main.yml
βββ meta
β βββ main.yml
βββ tasks
β βββ main.yml
βββ tests
β βββ inventory
β βββ test.yml
βββ vars
βββ main.yml
7 directories, 9 files
ubuntu@ip-10-0-1-223:~$ cat apache_role/files/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ansible Deployment</title>
</head>
<body>
<div class="header">
<h1>Deployed from Ansible to Apache</h1>
</div>
</body>
</html>
Create Ansible Inventory Groups:
- I create an inventory file (
hosts.ini
) to define two groups,[apache]
and[nginx]
.
[all:vars]
ansible_user=ubuntu
[apache]
slave1 ansible_host=10.0.1.65
slave2 ansible_host=10.0.1.233
[nginx]
slave3 ansible_host=10.0.1.210
slave4 ansible_host=10.0.1.85
apache_role/tasks/main.yml
---
- name: Install Apache
apt:
name: apache2
state: present
notify: start apache
- name: Gather the Apache service facts
service_facts:
- name: Push custom HTML file for Apache
copy:
src: index.html
dest: /var/www/html/index.html
group: root
mode: '0644'
when: ansible_facts.services["apache2.service"] is defined and ansible_facts.services["apache2.service"].state == "running"
notify: reload apache
- name: Display post-installation message for Apache
debug:
msg: "Apache installation and configuration complete!"
%%
Warning
service_facts:
required bywhen:
name: Gather the Apache service facts service_facts:
%%
apache_role/handlers/main.yml
---
- name: start apache
service:
name: apache2
state: started
- name: reload apache
ansible.builtin.service:
name: apache2
state: reloaded
%%
notify: start apache
In Ansible, the
notify
directive is used to trigger a handler based on the result of a task. If a task results in a change on the managed hostβfor instance, if a package like Apache is installed or updatedβthe task will notify the handler to take an action. Handlers are typically used to restart services or perform any action that is required after a change.
%%
nginx_role/tasks/main.yml
---
# tasks file for nginx_role
- name: Install NGINX
apt:
name: nginx
state: present
update_cache: yes
notify: start nginx
- name: Gather the NGINX service facts
service_facts:
- name: Push custom HTML file for NGINX
ansible.builtin.copy:
src: index.html
dest: /var/www/html/index.nginx-debian.html
owner: root
group: root
mode: '0644'
when: ansible_facts.services["nginx.service"] is defined and ansible_facts.services["nginx.service"].state == "running"
notify: reload nginx
- name: Display post-installation message for NGINX
debug:
msg: "NGINX installation and configuration complete!"
nginx_role/handlers/main.yml
---
# handlers file for nginx_setup
- name: start nginx
service:
name: nginx
state: started
- name: reload nginx
ansible.builtin.service:
name: nginx
state: reloaded
site.yml:
---
- hosts: apache
become: yes
roles:
- apache_role
- java_role
- hosts: nginx
become: yes
roles:
- nginx_role
To run these playbooks, I would use the ansible-playbook
command, specifying the inventory file and the main site playbook:
ansible-playbook -i hosts.ini site.yml
%%
Issue
Failure
Output when trying to start Apache manuallyPlaybook output
Solution
sudo systemctl stop nginx
Nginx was installed and running on this EC2 which was using the same port 80, a conflict. So we stop it
I re-run the playbook after stopping the nginx %%
Iβve executed the playbook multiple times already (troubleshooting an issue), resulting in all tasks being marked green. This indicates that the current state matches the desired state, and no changes were required. In addition, the appearance of our custom message confirms the successful execution of the playbook.
Success