Chapter 4: Managing Variables and Facts

Exercise: Managing variables

You will rewrite a web server play so that every package and service name comes from a variable, then add a second play that checks the site is reachable.

The play targets the webserver group, which contains servera.lab.example.com. Define these variables in the play's vars section:

VariableValueUsed for
web_pkghttpdWeb server package to install
firewall_pkgfirewalldFirewall package to install
web_servicehttpdWeb service to manage
firewall_servicefirewalldFirewall service to manage
python_pkgpython3-PyMySQLExtra Python package the course installs alongside the others
rulehttpfirewalld service to open

Managing variables

  • Define variables in a playbook.
  • Create tasks that use those variables.

Prerequisites: Complete control-node setup and the preceding lessons in this chapter. Run commands as student on workstation unless a step names another machine.

From the project directory, run the relevant home-lab check. For an exercise with several checkpoints, grade each state before changing or removing it:

lab grade data-variables

The grader reads project files and host state. A passing report covers the listed checks; also perform the task’s independent connection, repeat-run, and reboot checks where requested.

Change one package or service variable to an invalid value. Identify which task fails and why, then restore it.

Record the published result first. The grader checks the original requirements, so a changed name or value may intentionally fail those checks.

Deploy the web service on servera with playbook.yml, using the six variables in the table above.

  • Package, service, and firewall names must come from those variables, so changing a value changes the corresponding task's behavior.
  • The required packages must be current, the services running and enabled, and HTTP allowed now and persistently.
  • The page must say Example web content.
  • A separate unprivileged play on workstation must verify an HTTP 200 response.

Move into the project directory

[student@workstation ~]$ cd ~/data-variables
[student@workstation data-variables]$

Start the play and define its variables

Create playbook.yml with a play named Deploy and start Apache HTTPD service for the webserver group, and a vars section holding the six variables from the table.

---
- name: Deploy and start Apache HTTPD service
  hosts: webserver
  vars:
    web_pkg: httpd
    firewall_pkg: firewalld
    web_service: httpd
    firewall_service: firewalld
    python_pkg: python3-PyMySQL
    rule: http

Install the packages with one task

Add a tasks section and a first task that uses ansible.builtin.dnf to make sure the latest versions of the three packages are installed. The module's name accepts a list, so one task is enough. Remember to quote each list item, because each one starts with {{.

  tasks:
    - name: Required packages are installed and up to date
      ansible.builtin.dnf:
        name:
          - "{{ web_pkg }}"
          - "{{ firewall_pkg }}"
          - "{{ python_pkg }}"
        state: latest

Start and enable both services

ansible.builtin.service manages exactly one service per task, so write two tasks. Variables work in task names too.

    - name: The {{ firewall_service }} service is started and enabled
      ansible.builtin.service:
        name: "{{ firewall_service }}"
        enabled: true
        state: started

    - name: The {{ web_service }} service is started and enabled
      ansible.builtin.service:
        name: "{{ web_service }}"
        enabled: true
        state: started

In chapter 5 you will learn to do both with a single looping task.

Deploy some web content

    - name: Web content is in place
      ansible.builtin.copy:
        content: "Example web content"
        dest: /var/www/html/index.html

Open the firewall

Use ansible.posix.firewalld to allow the service named in rule, permanently and immediately.

    - name: The firewall port for {{ rule }} is open
      ansible.posix.firewalld:
        service: "{{ rule }}"
        permanent: true
        immediate: true
        state: enabled

Add a verification play

Add a second play, Verify the Apache service, that runs on workstation without privilege escalation, and uses ansible.builtin.uri to check that http://servera.lab.example.com returns status 200.

- name: Verify the Apache service
  hosts: workstation
  become: false
  tasks:
    - name: Ensure the webserver is reachable
      ansible.builtin.uri:
        url: http://servera.lab.example.com
        status_code: 200

Check the syntax

[student@workstation data-variables]$ ansible-navigator run \
> -m stdout playbook.yml --syntax-check
playbook: /home/student/data-variables/playbook.yml

Run the playbook

Watch the variable values appear in the task names:

[student@workstation data-variables]$ ansible-navigator run -m stdout playbook.yml
...output omitted...
TASK [The firewalld service is started and enabled] ****************************
ok: [servera.lab.example.com]

TASK [The httpd service is started and enabled] ********************************
changed: [servera.lab.example.com]
...output omitted...
TASK [The firewall port for http is open] **************************************
changed: [servera.lab.example.com]
...output omitted...
PLAY RECAP *********************************************************************
servera.lab.example.com    : ok=6    changed=4    unreachable=0    failed=0  ...
workstation                : ok=2    changed=0    unreachable=0    failed=0  ...

Finish

Check your work with lab grade data-variables, then put the exercise away with lab finish data-variables.