52

I'm using Ansible to provision my development server.

I want it to always start some services for me. I have handlers for this purpose but what is the best way to trigger handler execution without condition, e.g. make it always work?

Something like this:

tasks: - name: Trigger handler run_handler: name=nginx-restart 
2
  • 6
    If you want a task to always run you should make it a task rather than a handler. Commented Feb 12, 2015 at 15:21
  • @Jordan - sometimes you may want to have a handler that's conditionally triggered in most scenarios except this particular one. Commented Jul 30, 2017 at 19:15

3 Answers 3

91

If you absolutely need to trigger a handler every time then here are two options:

1) run a noop shell command which will always report as changed

- name: trigger nginx-restart command: /bin/true notify: nginx-restart 

2) use debug along with changed_when: to trigger a handler

- debug: msg="trigger nginx-restart" notify: nginx-restart changed_when: true 

Also of note for Option 1 and Check Mode: You may want to use check_mode: no if using Ansible version 2.2 or higher or always_run: yes if using earlier versions than that so that the task does not get skipped over in check mode. From my manual testing it looks like the handlers remain in check mode, but please be careful as your case may differ.

5
  • 9
    Nowadays, you can ` --force-handlers run handlers even if a task fails` Commented May 7, 2015 at 8:34
  • 6
    Yes though that will force all handlers to run Commented May 8, 2015 at 9:45
  • i found this post useful regarding the changed status, that lead me here. serverfault.com/a/799282/173002. ty. Commented Jan 10, 2018 at 1:38
  • Thanks, I used option 2 and a changed_when with more logic in it to implement a non-idempotent task [which may be invoked more than once in some cases] as a handler rather than a task. Commented Nov 29, 2018 at 0:27
  • For me a combination of both options did it, as I needed the task itself to check a variable using when. Thanks! Commented Aug 12, 2020 at 11:32
21

Ansible provides several options for forcing handlers:

  1. To always force all handlers, run ansible-playbook playbook.yml --force-handlers, as documented here: https://github.com/ansible/ansible/issues/4777

  2. To force handlers that have been notified at a specific point within a playbook, you can use a meta task https://docs.ansible.com/playbooks_intro.html:

 tasks: - shell: some tasks go here - meta: flush_handlers - shell: some other tasks 
  1. However, it sounds like you just want to make sure a service is running or restarted, regardless of the outcome of another task. In that case, don't use a handler, use a new task that calls Ansible's service module: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/service_module.html
 tasks: - name: ensure ntp is running service: name=ntp state=started enabled=yes - name: always reload nginx service: name=nginx state=reloaded - name: always restart MySQL service: name=mysql state=restarted 
8
  • 2
    The problem with (3) is that one might have several tasks which notify the handler, and I don't want the handler to run (restarting the service) several times. Commented Oct 7, 2015 at 10:51
  • Multiple tasks can notify the same handler, and the handler will only execute once. That's the whole point of handlers. Commented Dec 2, 2015 at 19:37
  • Hey Jeff. This answer is about not using handlers, specifying all actions just using tasks. Commented Dec 4, 2015 at 23:38
  • 1
    I don't need a new question. The OQ asked "How can I make sure a handler ALWAYS runs", and this answer, part 3, suggested "Use tasks instead", and my comment points out "Your task might then run several times in some circumstances." Commented Dec 7, 2015 at 14:17
  • 2
    I believe the documentation you refer to in issue #4777 is incorrect: --force-handlers does not unconditionally run all handlers. unix.stackexchange.com/a/327595/29483 The behaviour of --force-handlers, which is correctly documented nearly everywhere else e.g. in the man page and the ansible user guide, is that notified handlers will be run even if the play stops early due to a failed task. Commented May 17, 2018 at 11:24
11

Restarting a service is one thing; ensuring it is running is another. If you want ansible to make sure nginx is running, you do this:

tasks: - name: Ensure nginx is running service: name=nginx state=started 

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.