Bookmark this page

Guided Exercise: Managing Facts

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

  1. Change into the /home/student/data-facts directory.

    [student@workstation ~]$ cd ~/data-facts
    [student@workstation data-facts]$
  2. 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_facts

    Use 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
  3. 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.

    1. 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.
    2. 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.yml
      
      PLAY [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
  4. 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.

    1. 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'] }}"
    2. 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
  5. 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.

    1. 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
    2. 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
  6. 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.

    1. Create a play in the playbook.yml playbook with the following name and hosts directive:

      ---
      - name: Install Apache and starts the service
        hosts: webserver
    2. 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: latest
    3. Create 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'] }}"
    4. 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'] }}"
  7. 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-check
    
    playbook: /home/student/data-facts/playbook.yml
  8. Create and run a playbook called check_httpd.yml to verify that the httpd service is not currently running on servera.

    1. 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: result
    2. Run 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.
  9. 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.yml
    
    PLAY [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
  10. 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...

Finish

On the workstation machine, change to the student user home directory and use the lab command to complete this exercise. This step is important to ensure that resources from previous exercises do not impact upcoming exercises.

[student@workstation ~]$ lab finish data-facts

This concludes the section.

Revision: rh294-9.0-c95c7de