In this exercise, you implement handlers in playbooks.
Outcomes
You should be able to define handlers in playbooks and notify them to apply configuration changes.
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 control-handlers
Procedure 4.2. Instructions
On the workstation machine, open a new terminal and change to the /home/student/control-handlers directory.
[student@workstation ~]$ cd ~/control-handlers
[student@workstation control-handlers]$Edit the configure_webapp.yml playbook file.
This playbook installs and configures a web application server.
When the web application server configuration changes, the playbook triggers a restart of the appropriate service.
Review the configure_webapp.yml playbook.
It begins with the initialization of some variables:
---
- name: Web application server is deployed
hosts: webapp
vars:
packages:
- nginx
- php-fpm
web_service: nginx
app_service: php-fpm
resources_dir: /home/student/control-handlers/files
web_config_src: "{{ resources_dir }}/nginx.conf.standard"
web_config_dst: /etc/nginx/nginx.conf
app_config_src: "{{ resources_dir }}/php-fpm.conf.standard"
app_config_dst: /etc/php-fpm.conf
tasks:
| |
| |
| |
| |
| |
| |
| |
|
In the configure_webapp.yml file, define a task that uses the ansible.builtin.dnf module to install the required packages as defined by the packages variable.
The task should read as follows:
tasks:
- name: "{{ packages }} packages are installed"
ansible.builtin.dnf:
name: "{{ packages }}"
state: presentAdd two tasks to start and enable the web and application server services. The tasks should read as follows:
- name: Make sure the web service is running
ansible.builtin.service:
name: "{{ web_service }}"
state: started
enabled: true
- name: Make sure the application service is running
ansible.builtin.service:
name: "{{ app_service }}"
state: started
enabled: trueAdd a task to download nginx.conf.standard to /etc/nginx/nginx.conf on the managed host, using the ansible.builtin.copy module.
Add a condition that notifies the restart web service handler to restart the web server service after a configuration file change.
The task should read as follows:
- name: The {{ web_config_dst }} file has been deployed
ansible.builtin.copy:
src: "{{ web_config_src }}"
dest: "{{ web_config_dst }}"
force: true
notify:
- restart web serviceAdd a task to download php-fpm.conf.standard to /etc/php-fpm.conf on the managed host, using the ansible.builtin.copy module.
Add a condition that notifies the restart app service handler to restart the application server service after a configuration file change.
The task should read as follows:
- name: The {{ app_config_dst }} file has been deployed
ansible.builtin.copy:
src: "{{ app_config_src }}"
dest: "{{ app_config_dst }}"
force: true
notify:
- restart app serviceAdd the handlers keyword to define the start of the handler tasks.
Define the first handler, restart web service, which restarts the nginx service.
The handler should read as follows:
handlers:
- name: restart web service
ansible.builtin.service:
name: "{{ web_service }}"
state: restartedDefine the second handler, restart app service, which restarts the php-fpm service.
The handler should read as follows:
- name: restart app service
ansible.builtin.service:
name: "{{ app_service }}"
state: restartedThe completed playbook should consist of the following content:
---
- name: Web application server is deployed
hosts: webapp
vars:
packages:
- nginx
- php-fpm
web_service: nginx
app_service: php-fpm
resources_dir: /home/student/control-handlers/files
web_config_src: "{{ resources_dir }}/nginx.conf.standard"
web_config_dst: /etc/nginx/nginx.conf
app_config_src: "{{ resources_dir }}/php-fpm.conf.standard"
app_config_dst: /etc/php-fpm.conf
tasks:
- name: "{{ packages }} packages are installed"
ansible.builtin.dnf:
name: "{{ packages }}"
state: present
- name: Make sure the web service is running
ansible.builtin.service:
name: "{{ web_service }}"
state: started
enabled: true
- name: Make sure the application service is running
ansible.builtin.service:
name: "{{ app_service }}"
state: started
enabled: true
- name: The {{ web_config_dst }} file has been deployed
ansible.builtin.copy:
src: "{{ web_config_src }}"
dest: "{{ web_config_dst }}"
force: true
notify:
- restart web service
- name: The {{ app_config_dst }} file has been deployed
ansible.builtin.copy:
src: "{{ app_config_src }}"
dest: "{{ app_config_dst }}"
force: true
notify:
- restart app service
handlers:
- name: restart web service
ansible.builtin.service:
name: "{{ web_service }}"
state: restarted
- name: restart app service
ansible.builtin.service:
name: "{{ app_service }}"
state: restartedBefore running the playbook, verify that its syntax is correct by running ansible-navigator with the --syntax-check option.
Correct any reported errors before moving to the next step.
You should see output similar to the following:
[student@workstation control-handlers]$ansible-navigator run \>-m stdout configure_webapp.yml --syntax-checkplaybook: /home/student/control-handlers/configure_webapp.yml
Run the configure_webapp.yml playbook.
The output shows that the handlers are being executed.
[student@workstation control-handlers]$ansible-navigator run \>-m stdout configure_webapp.ymlPLAY [Web application server is deployed] ************************************ TASK [Gathering Facts] ******************************************************* ok: [servera.lab.example.com] TASK [['nginx', 'php-fpm'] packages are installed] *************************** changed: [servera.lab.example.com] TASK [Make sure the web service is running] ********************************** changed: [servera.lab.example.com] TASK [Make sure the application service is running] ************************** changed: [servera.lab.example.com] TASK [The /etc/nginx/nginx.conf file has been deployed] ********************** changed: [servera.lab.example.com] TASK [The /etc/php-fpm.conf file has been deployed] ************************** changed: [servera.lab.example.com] RUNNING HANDLER [restart web service] **************************************** changed: [servera.lab.example.com] RUNNING HANDLER [restart app service] **************************************** changed: [servera.lab.example.com] PLAY RECAP ******************************************************************* servera.lab.example.com : ok=8 changed=7 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Run the playbook again.
[student@workstation control-handlers]$ansible-navigator run \>-m stdout configure_webapp.ymlPLAY [Web application server is deployed] ************************************ TASK [Gathering Facts] ******************************************************* ok: [servera.lab.example.com] TASK [['nginx', 'php-fpm'] packages are installed] *************************** changed: [servera.lab.example.com] TASK [Make sure the web service is running] ********************************** changed: [servera.lab.example.com] TASK [Make sure the application service is running] ************************** changed: [servera.lab.example.com] TASK [The /etc/nginx/nginx.conf file has been deployed] ********************** changed: [servera.lab.example.com] TASK [The /etc/php-fpm.conf file has been deployed] ************************** changed: [servera.lab.example.com] PLAY RECAP ******************************************************************* servera.lab.example.com : ok=6 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
This time the handlers are skipped.
If the remote /etc/nginx/nginx.conf configuration file is changed in the future, executing the playbook would trigger the restart web service handler but not the restart app service handler.
This concludes the section.