In this exercise, you gather Ansible facts from a managed host and use them in plays.
Outcomes
You should be able to:
Gather facts from a host.
Create tasks that use the gathered facts.
As the student user on the workstation machine, use the lab command to prepare your system for this exercise.
This command prepares your environment and ensures that all required resources are available.
[student@workstation ~]$ lab start data-facts
Procedure 3.3. Instructions
Change into the /home/student/data-facts directory.
[student@workstation ~]$ cd ~/data-facts
[student@workstation data-facts]$Use the Ansible debug module to view facts.
Create a playbook called display_facts.yml that contains a play that displays facts for the webserver host.
---
- name: Display ansible_facts
hosts: webserver
tasks:
- name: Display facts
debug:
var: ansible_factsUse the ansible-navigator command to run the display_facts.yml playbook.
Review the output and observe the values of some variables it displays.
[student@workstation data-facts]$ansible-navigator run \>-m stdout display_facts.yml...output omitted... "system": "Linux", "system_capabilities": [], "system_capabilities_enforced": "False", "system_vendor": "Red Hat", "uptime_seconds": 6775, "user_dir": "/root", "user_gecos": "root", "user_gid": 0, "user_id": "root", "user_shell": "/bin/bash", "user_uid": 0, "userspace_architecture": "x86_64", "userspace_bits": "64", "virtualization_role": "guest", "virtualization_tech_guest": [ "openstack" ], "virtualization_tech_host": [ "kvm" ], "virtualization_type": "openstack" } } PLAY RECAP ********************************************************************* servera.lab.example.com : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Use the Ansible debug module to view specific facts.
Create and run a playbook called display_specific_facts.yml that contains a play that displays specific facts for the webserver host.
Create a play in the playbook display_specific_facts.yml that contains a play to show specific facts for the webserver host.
---
- name: Display specific ansible_facts
hosts: webserver
tasks:
- name: Display specific facts
debug:
msg: >
Host "{{ ansible_facts['fqdn'] }}" with Python version "{{ ansible_facts['python_version'] }}" has "{{ ansible_facts['processor_count'] }}" processors and "{{ ansible_facts['memtotal_mb'] }}" MiB of total system memory.Use the ansible-navigator command to run the display_specific_facts.yml playbook and review the output.
[student@workstation data-facts]$ansible-navigator run \>-m stdout display_specific_facts.ymlPLAY [Display specific ansible_facts] ****************************************** TASK [Gathering Facts] ********************************************************* ok: [servera.lab.example.com] TASK [Display specific facts] ************************************************** ok: [servera.lab.example.com] => { "msg": "Host \"servera.lab.example.com\" with Python version \"3.9.10\" has \"1\" processors and \"960\" MiB of total system memory.\n" } PLAY RECAP ********************************************************************* servera.lab.example.com : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Add a play to the display_specific_facts.yml playbook that displays the current value of the ansible_local variable.
Run the playbook.
The resulting output shows that the variable is empty or undefined, because no custom facts are set for your managed hosts at this point.
Add a task to the display_specific_facts.yml playbook that displays the current value of the ansible_local variable.
The full playbook should look like the following example:
---
- name: Display specific ansible_facts
hosts: webserver
tasks:
- name: Display specific facts
debug:
msg: >
Host "{{ ansible_facts['fqdn'] }}" with Python version "{{ ansible_facts['python_version'] }}" has "{{ ansible_facts['processor_count'] }}" processors and "{{ ansible_facts['memtotal_mb'] }}" MiB of total system memory.
- name: Display ansible_local variable
debug:
msg: The ansible_local variable is set to "{{ ansible_facts['ansible_local'] }}"Run the display_specific_facts.yml playbook again.
[student@workstation data-facts]$ansible-navigator run \>-m stdout display_specific_facts.yml...output omitted... TASK [Display ansible_local variable] ****************************************** ok: [servera.lab.example.com] => { "msg": "The ansible_local variable is set to \"{}\"" } PLAY RECAP ********************************************************************* servera.lab.example.com : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Create the /etc/ansible/facts.d directory on servera, then create the custom.fact file in that directory.
The fact file defines the package to install and the service to start on servera.
Create the /etc/ansible/facts.d directory on servera.
[student@workstation data-facts]$ssh servera[student@servera ~]$sudo mkdir -p /etc/ansible/facts.d[sudo] password for student:student
Create the custom.fact file in the /etc/ansible/facts.d directory on servera.
You need to be root in order to create a file in that directory, but make sure that you return to the student account after creating and editing the file but before continuing this activity.
The contents of the file should read as follows:
[general] package = httpd service = httpd state = started enabled = true
Create a playbook named playbook.yml that contains a single play.
That play runs on the managed hosts in the webserver host group.
It uses custom facts to install a package and ensure a network service is in a particular state on each host in the group.
Create a play in the playbook.yml playbook with the following name and hosts directive:
--- - name: Install Apache and starts the service hosts: webserver
Create the first task for that play.
It should make sure that the latest version of the package referenced by the ansible_facts['ansible_local']['custom']['general']['package'] custom fact for the managed host is installed.
tasks:
- name: Install the required package
dnf:
name: "{{ ansible_facts['ansible_local']['custom']['general']['package'] }}"
state: latestCreate another task that uses the ansible_facts['ansible_local']['custom']['general']['service'] custom fact to control the specified service.
That task must also use the ansible_facts['ansible_local']['custom']['general']['state'] custom fact to determine whether or not to start or stop the service, and the ansible_facts['ansible_local']['custom']['general']['enabled'] custom fact to control whether or not it is started when the system boots.
- name: Start the service
service:
name: "{{ ansible_facts['ansible_local']['custom']['general']['service'] }}"
state: "{{ ansible_facts['ansible_local']['custom']['general']['state'] }}"
enabled: "{{ ansible_facts['ansible_local']['custom']['general']['enabled'] }}"The complete playbook should consist of the following content. Review the playbook contents and ensure that all the tasks are defined.
---
- name: Install Apache and starts the service
hosts: webserver
tasks:
- name: Install the required package
dnf:
name: "{{ ansible_facts['ansible_local']['custom']['general']['package'] }}"
state: latest
- name: Start the service
service:
name: "{{ ansible_facts['ansible_local']['custom']['general']['service'] }}"
state: "{{ ansible_facts['ansible_local']['custom']['general']['state'] }}"
enabled: "{{ ansible_facts['ansible_local']['custom']['general']['enabled'] }}"Verify the syntax of the playbook.yml playbook by running the ansible-navigator run --syntax-check command.
Correct any reported errors before moving to the next step.
You should see output similar to the following example:
[student@workstation data-facts]$ansible-navigator run \>-m stdout playbook.yml --syntax-checkplaybook: /home/student/data-facts/playbook.yml
Create and run a playbook called check_httpd.yml to verify that the httpd service is not currently running on servera.
Create and run a playbook called check_httpd.yml with the following contents:
---
- name: Check httpd status
hosts: webserver
tasks:
- name: Check httpd status
command: systemctl status httpd
register: result
- name: Display http status
debug:
var: resultRun the check_httpd.yml playbook and verify that the httpd service is not currently running on the servera machine.
[student@workstation data-facts]$ansible-navigator run \>-m stdout check_httpd.yml...output omitted... TASK [Check httpd status] ****************************************************** fatal: [servera.lab.example.com]: FAILED! => {"changed": false, "msg": "Could not find the requested service httpd: host"} PLAY RECAP ********************************************************************* servera.lab.example.com : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0 Please review the log for errors.
Run the playbook.yml playbook using the ansible-navigator run command.
Watch the output as Ansible installs the package and then enables the service.
[student@workstation data-facts]$ansible-navigator run \>-m stdout playbook.ymlPLAY [Install Apache and start the service] ************************************ TASK [Gathering Facts] ********************************************************* ok: [servera.lab.example.com] TASK [Install the required package] ******************************************** changed: [servera.lab.example.com] TASK [Start the service] ******************************************************* changed: [servera.lab.example.com] PLAY RECAP ********************************************************************* servera.lab.example.com : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Run the check_httpd.yml playbook again to determine whether the httpd service is now running on the servera machine.
[student@workstation data-facts]$ansible-navigator run \>-m stdout check_httpd.yml...output omitted... "stdout_lines": [ "● httpd.service - The Apache HTTP Server", " Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)", " Active:active (running)since Tue 2022-06-21 19:09:06 EDT; 22s ago", ...output omitted...
This concludes the section.