3
votes

Is it possible in Ansible to conditionally notify handlers only if they are present in that play?

For example: I have a playbook for multiple host configurations. Some hosts run PHP with Apache and some with PHP-FPM. Depending upon the host, different handlers need running when PHP is modifued.

This is a simple example of the issue:

- name: copy php.ini
  copy:
    src=roles/php/templates/{{ php_template }}/php.ini
    dest=/etc/
  notify:
    - reload php-fpm
    - reload apache

Obviously, what I want to do is notify the correct software to reload when the php.ini file changes. However Ansible gives an error because only one of the handlers is present in the play at any time e.g:

ERROR: change handler (reload php-fpm) is not defined

Is there a way to achieve this without creating errors or duplicating Ansible code?
Thanks in advance

2
Have you tried to set the handler name in a variable which you set to the proper handler per host?Sebastian Stigler
I had seen an reference to that, I wasn't sure how best to automate that whilst keeping tasks "mostly" abstract and not create obscure dependencies between them.Steve E.

2 Answers

4
votes

In the end, I found a solution by detecting the presence of related roles and using that to determine which handlers to run. If you can see a shorter way, please post an answer.

roles/php/tasks/main.yml
----
- name: detect apache
  shell: 
    'ls /etc/init.d/ | grep httpd | wc -l'
  register:
    httpd_exists
- name: detect php-fpm
  shell: 
    'ls /etc/init.d/ | grep php-fpm | wc -l'
  register:
    phpfpm_exists

And then create local notifier for each related handler:

 notify:
   - php reload apache
   - php reload php-fpm

And then still in the same role, add conditions to the local handlers.

roles/php/handlers/main.yml
---
- name: php reload apache
  include: ../../apache/handlers/main.yml
  when: (httpd_exists.stdout == '1')

- name: php reload php-fpm
  include: ../../php-fpm/handlers/main.yml
  when: (phpfpm_exists.stdout == '1')
0
votes

A playbook has access to the vars defined in the role. So you could create a var "role_apache: true" in roles/apache/vars/main.yml and use that in the conditional.

That var would also be accessible in roles/php and roles/php-fhm if you had those in the same playbook. Even if you skipped one of them.