Bookmark this page

Guided Exercise: Implementing Handlers

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

  1. 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]$
  2. 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.

    1. Review the configure_webapp.yml playbook. It begins with the initialization of some variables:

      ---
      - name: Web application server is deployed
        hosts: webapp
        vars:
          packages: 1
            - nginx
            - php-fpm
          web_service: nginx 2
          app_service: php-fpm 3
          resources_dir: /home/student/control-handlers/files 4
          web_config_src: "{{ resources_dir }}/nginx.conf.standard" 5
          web_config_dst: /etc/nginx/nginx.conf 6
          app_config_src: "{{ resources_dir }}/php-fpm.conf.standard" 7
          app_config_dst: /etc/php-fpm.conf 8
      
        tasks:

      1

      packages specifies the name of the packages to install for the web application services.

      2

      web_service specifies the name of the web server service.

      3

      app_service specifies the name of the application server service.

      4

      resources_dir specifies the directory where configuration files are located.

      5

      web_config_src specifies the location of the web server configuration file to install.

      6

      web_config_dst: specifies the location of the installed web server configuration file on the managed hosts.

      7

      app_config_src specifies the location of the application server configuration file to install.

      8

      web_config_dst: specifies the location of the installed application server configuration file on the managed hosts.

    2. 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: present
    3. Add 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: true
    4. Add 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 service
    5. Add 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 service
    6. Add 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: restarted
    7. Define 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: restarted

      The 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: restarted
  3. Before 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-check
    
    playbook: /home/student/control-handlers/configure_webapp.yml
  4. 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.yml
    
    PLAY [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
  5. Run the playbook again.

    [student@workstation control-handlers]$ ansible-navigator run \
    > -m stdout configure_webapp.yml
    
    PLAY [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.

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 control-handlers

This concludes the section.

Revision: rh294-9.0-c95c7de