Deploying NGINX locally using Ansible

Christian Talavera
4 min readAug 10, 2021

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": [
...............................................
...............................................
...............................................
...............................................
...............................................
...............................................
...............................................
...............................................
...............................................
...............................................

--

--