Deploying NGINX locally using Ansible
As an example of Ansible in action, NGINX can be deployed using a Ansible Playbook. A configuration can be declared using the modules in a Playbook.
Steps will be spelled out on how NGINX will be deployed, on all relevant servers, using a Playbook written in YAML named playbook_nginx_install.yaml
:
$ nano playbook_nginx_install.yaml
The YAML file starts with three dashes — — starting the first block.
Nested one level, as indicated by a dash -
within the block
is the hosts:
statement, representing the server grouping for the Playbook to target, which would be the group local
in this example, containing only localhost
.
Another nested statement within the block
is the become:
statement, indicating on if this task will run with elevated privileges; in this case the task is installing an application, so it would need elevated privileges to run properly and needs the value to be set as true
:
---
- hosts: local
become: true
The next statement will also be at the same indentation level, which will be the tasks:
statement
Nested within this will be the first task; the name:
statement holds the description of the task.
On the same indentation level, the module
being used will be expressed; this will use the yum:
module to install the NGINX software.
Indented one level deeper would be the name:
statement, representing the application needing installation; the state:
statement represents the task to be done, in this case the module will check to see if NGINX is installed, and will do so if not, so the value will be set to present
:
---
- hosts: local
become: true
tasks:
- name: Install the NGINX application on localhost
yum:
name: nginx
state: present
The same thing can be repeated for the service
module, which will start the NGINX service.
Nested within the service module is the name:
statement, representing the application needing to be manipulated; the state:
statement represents the action to be performed, in this case to start the service, the value will be set to started:
---
- hosts: local
become: true
tasks:
- name: Install the NGINX application on localhost
yum:
name: nginx
state: present
- name: Start the NGINX service
service:
name: nginx
state: started
Running the Playbook demonstrates that the install of NGINX is successful:
$ sudo ansible-playbook playbook_nginx_install.yaml --connection=local
PLAY [local] ****************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************
ok: [127.0.0.1]
TASK [Install the NGINX application on localhost] ***************************************************************
changed: [127.0.0.1]
TASK [Start the NGINX service] **********************************************************************************
changed: [127.0.0.1]
PLAY RECAP ******************************************************************************************************
127.0.0.1 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Since Ansible is idempotent, running the Playbook again will perform no changes:
$ sudo ansible-playbook playbook_nginx_install.yaml --connection=local
PLAY [local] ****************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************
ok: [127.0.0.1]
TASK [Install the NGINX application on localhost] ***************************************************************
ok: [127.0.0.1]
TASK [Start the NGINX service] **********************************************************************************
ok: [127.0.0.1]
PLAY RECAP ******************************************************************************************************
127.0.0.1 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Based on the created playbook_nginx_install.yaml
Playbook, a version can be created, named playbook_nginx_uninstall.yaml
, that would do the mirror.
The NGINX service will be stopped, and the application installed; the other Playbook’s content is listed below:
---
- hosts: local
become: true
tasks:
- name: Stop the NGINX service
service:
name: nginx
state: stopped
- name: Uninstall the NGINX application on localhost
yum:
name: nginx
state: absent
Running the Playbook demonstrates that the NGINX application is successfully removed:
$ sudo ansible-playbook playbook_nginx_uninstall.yaml --connection=local
PLAY [local] ****************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************
ok: [127.0.0.1]
TASK [Stop the NGINX service] ***********************************************************************************
changed: [127.0.0.1]
TASK [Uninstall the NGINX application on localhost] *************************************************************
changed: [127.0.0.1]
PLAY RECAP ******************************************************************************************************
127.0.0.1 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Ansible Playbook Fact Gathering
Every time Ansible is run on a server, it automatically gathers important facts about that particular host; this can be done with the following command if a server target group is provided:
$ ansible <SERVER_TARGET_GROUP> -m setup
The output is very verbose, demonstrating how much fact information Ansible is able to gather from a host:
127.0.0.1 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"172.17.0.1",
"192.168.1.175",
"192.168.122.1"
],
"ansible_all_ipv6_addresses": [
"fe80::f193:1ac:91d2:68f9"
],
"ansible_apparmor": {
"status": "disabled"
},
"ansible_architecture": "x86_64",
"ansible_bios_date": "09/08/2016",
"ansible_bios_version": "T303UA.302",
"ansible_cmdline": {
"BOOT_IMAGE": "(hd0,gpt3)/boot/vmlinuz-5.12.13-300.fc34.x86_64",
"quiet": true,
"resume": "UUID=6a973621-a650-4743-82b1-c634ad009736",
"rhgb": true,
"ro": true,
"root": "UUID=a3d797a4-328d-48a0-b4e4-226adec5433f"
},
"ansible_date_time": {
"date": "2021-07-08",
"day": "08",
"epoch": "1625771972",
"hour": "15",
"iso8601": "2021-07-08T19:19:32Z",
"iso8601_basic": "20210708T151932964070",
"iso8601_basic_short": "20210708T151932",
"iso8601_micro": "2021-07-08T19:19:32.964070Z",
"minute": "19",
"month": "07",
"second": "32",
"time": "15:19:32",
"tz": "EDT",
"tz_offset": "-0400",
"weekday": "Thursday",
"weekday_number": "4",
"weeknumber": "27",
"year": "2021"
},
"ansible_default_ipv4": {
"address": "192.168.1.175",
"alias": "wlp58s0",
"broadcast": "192.168.1.255",
"gateway": "192.168.1.1",
"interface": "wlp58s0",
"macaddress": "78:92:9c:e3:d2:b2",
"mtu": 1500,
"netmask": "255.255.255.0",
"network": "192.168.1.0",
"type": "ether"
},
"ansible_default_ipv6": {},
"ansible_device_links": {
"ids": {
"sda": [
"ata-HFS512G39MND-3510A_FJ63N432010903I2R"
],
"sda1": [
"ata-HFS512G39MND-3510A_FJ63N432010903I2R-part1"
],
"sda2": [
"ata-HFS512G39MND-3510A_FJ63N432010903I2R-part2"
],
"sda3": [
"ata-HFS512G39MND-3510A_FJ63N432010903I2R-part3"
],
"sda4": [
...............................................
...............................................
...............................................
...............................................
...............................................
...............................................
...............................................
...............................................
...............................................
...............................................