Vijesh Kk
Vijesh Kk

Reputation: 171

ansible - run handler only if any task in role changed

I created a handler to reboot server and I have a role which sets up the os with several configuration (around 6 tasks in this role) and I want to trigger reboot server handler only if any of the task in the entire role is changed and that too after completion of entire role.

I tried to put 'notify' at the playbook for the role. but got error that ERROR! 'notify' is not a valid attribute for a Play

site.yml

---
- name: Setup OS parameters
  hosts: master_servers
  roles:
    - os_prep
  tags: os_prep
  notify:
    - restart server

handler to reboot server

---
- name: restart server
  command: /sbin/shutdown -r now
  async: 0
  poll: 0
  ignore_errors: true
  notify:
    - check server status

- name: check server status
  wait_for:
    port: 22
    host: '{{ inventory_hostname }}'
    search_regex: OpenSSH
    delay: 10
    timeout: 60
  connection: local

After running the entire role 'os_prep', if any of the task in the role has 'changed' status, then restart server handler to be triggered.

Upvotes: 1

Views: 4964

Answers (1)

xenlo
xenlo

Reputation: 859

The notify is an attribute for a task, not for a play. So you should add notify: restart server to all your tasks of your role. Let's say all your tasks are in roles/os_prep/tasks/main.yml. It would look like something like this:

---
- name: Configure this
  template:
    src: myConfig.cfg.j2
    dest: /etc/myConfig.cfg
  notify: restart server

- name: Change that
  moduleX:
    …
  notify: restart server

- name: Add users
  user:
    name: "{{ item.key }}"
    home: "/home/{{ item.key }}"
    uid: "{{ item.value.uid }}"
  with_dict: "{{ users }}"
  notify: restart server

- …

The behavior of the handler will proceed like you expect. If any of those tasks get the changed status, it will run the reboot (only once) at the end of the play.

Note that according to me you should not apply the notify to the task that don't need a reboot. Usually only few stuffs need a server reboot. In my example here above adding user don't need a reboot afterward. And most of the time a service restart will be enough. But of course, I don't know your use-case.


Extra comments

Note 1

I see that you chain your handlers. Be aware that you could also use the listen attribute of handlers to do so. In you task you rather notify: Restart and wait server, and your roles/os_prep/handlers/main.yml will look like this:

---
- name: restart server
  command: /sbin/shutdown -r now
  async: 0
  poll: 0
  ignore_errors: true
  listen: Restart and wait server

- name: check server status
  wait_for:
    port: 22
    host: '{{ inventory_hostname }}'
    search_regex: OpenSSH
    delay: 10
    timeout: 60
  connection: local
  listen: Restart and wait server

Note 2

Please be aware that there is a reboot module too that you could use in place of the command: shutdown -r.

Here is the doc: https://docs.ansible.com/ansible/latest/modules/reboot_module.html

Upvotes: 3

Related Questions