0

If I will use a role for multiple operating systems, for example, FreeBSD & Linux, I use this structure for the task in main.yml:

---
- import_tasks: freebsd.yml
  when: ansible_os_family == "FreeBSD"
  tags:
    - foo

- import_tasks: debian.yml
  when: ansible_os_family == "Debian"
  tags:
    - foo

Can something similar be done for the handlers so that I could use the same name when restarting a service?

For example if having something like :

---
- name: my task
  template:
    src: test.j2
    dest: /tmp/test
  notify: restart service

in handlers/main.yml for FreeBSD I need:

- name: resart service
  service: 
    name: service 
    state: restarted

For Linux:

- name: resart service
  systemd:
    daemon_reload: true
    state: restarted
    enabled: true
nbari
  • 25,603
  • 10
  • 76
  • 131
  • Does this answer your question? [Ansible handler using if statements](https://stackoverflow.com/questions/43169426/ansible-handler-using-if-statements). Doc: [Handlers: running operations on change](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_handlers.html#handlers) and [Naming handlers](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_handlers.html#naming-handlers). – U880D Jan 16 '23 at 13:35
  • I would like to use use the same name, not an if statement like in the tasks – nbari Jan 16 '23 at 13:56
  • 1
    But the answer and the documentation shows how to use the "same name" via keyword `listen`. And how do you like to achieve the task with calling a handler based on a condition without defining the condition? Maybe you can edit your question, enhance it regarding that requirement and provide more description. – U880D Jan 16 '23 at 14:02
  • missed that you are correct – nbari Jan 16 '23 at 21:06

1 Answers1

1

You can ease your life in your tasks/main.yml file by using the first_found lookup and craft an adequate structure in your role. You can then use the exact same construct for your handlers. Here's a dummy very simple example, adapt and enhance according to your needs.

Test project structure:

$ tree
.
├── roles
│   └── acme
│       ├── handlers
│       │   ├── debian.yml
│       │   ├── freebsd.yml
│       │   └── main.yml
│       ├── tasks
│       │   ├── debian.yml
│       │   ├── freebsd.yml
│       │   ├── main.yml
│       │   └── unsupported.yml
│       └── vars
│           └── main.yml
└── test_playbook.yml

5 directories, 9 files

First the files in the acme demo role:

vars/main.yml

---
acme_candidate_includes:
  - "{{ ansible_os_family | lower }}.yml"
  - unsupported.yml

tasks/main.yml

---
- name: Load os specific tasks
  ansible.builtin.include_tasks: "{{ item }}"
  loop: "{{ q('first_found', acme_candidate_includes) }}"

tasks/debian.yml

---
- name: A task for debian
  ansible.builtin.shell: /usr/bin/true
  notify: dummy_handler

tasks/freebsd.yml

---
- name: A task for freebsd
  ansible.builtin.shell: /usr/bin/true
  notify: dummy_handler

tasks/unsupported.yml

---
- name: Fail on unsupported OS
  ansible.builtin.fail:
    msg: "{{ ansible_os_family }} is not supported by this role"

handlers/main.yml

---
# Note: falling back to unsupported is not really needed here
# as the role will fail early and never call the handler for
# unsupported OS. This still standardize our call but the
# `unsupported.yml` file is not needed in the folder.
- name: A dummy handler
  listen: dummy_handler
  ansible.builtin.include_tasks: "{{ item }}"
  loop: "{{ q('first_found', acme_candidate_includes) }}"

handlers/debian.yml

---
- name: A handler for debian
  ansible.builtin.debug:
    msg: I'm a debian handler

handlers/freebsd.yml

---
- name: A handler for freebsd
  ansible.builtin.debug:
    msg: I'm a freebsd handler

Now we wrap it up in test_playbook.yml

---
- name: Test playbook for os dependant handlers in roles demo
  hosts: localhost

  tasks:
    - name: Run our demo role
      ansible.builtin.import_role:
        name: acme

Which gives when executed on my Ubuntu host:

$ ansible-playbook test_playbook.yml 

PLAY [Test playbook for os dependant handlers in roles demo] ******************************************************************************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [acme : Load os specific tasks] ******************************************************************************************************************************************************************************************
included: /project/path/roles/acme/tasks/debian.yml for localhost => (item=/project/path/roles/acme/tasks/debian.yml)

TASK [acme : A task for debian] ***********************************************************************************************************************************************************************************************
changed: [localhost]

RUNNING HANDLER [acme : A dummy handler] **************************************************************************************************************************************************************************************
included: /project/path/roles/acme/handlers/debian.yml for localhost => (item=/project/path/roles/acme/handlers/debian.yml)

RUNNING HANDLER [acme : A handler for debian] *********************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "I'm a debian handler"
}

PLAY RECAP ********************************************************************************************************************************************************************************************************************
localhost                  : ok=5    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
Zeitounator
  • 38,476
  • 7
  • 53
  • 66