In response to a change, I have multiple related tasks that should run. How do I write an Ansible handler with multiple tasks?
For example, I would like a handler that restarts a service only if already started:
- name: Restart conditionally shell: check_is_started.sh register: result - name: Restart conditionally step 2 service: name=service state=restarted when: result
If you want to run multiple tasks in a playbook concurrently, use async with poll set to 0. When you set poll: 0 , Ansible starts the task and immediately moves on to the next task without waiting for a result. Each async task runs until it either completes, fails or times out (runs longer than its async value).
In a nutshell, handlers are special tasks that only get executed when triggered via the notify directive. Handlers are executed at the end of the play, once all tasks are finished. In Ansible, handlers are typically used to start, reload, restart, and stop services.
Notifying the same handler multiple times will result in executing the handler only once regardless of how many tasks notify it. For example, if multiple tasks update a configuration file and notify a handler to restart Apache, Ansible only bounces Apache once to avoid unnecessary restarts.
There is proper solution to this problem as of Ansible 2.2.
handlers can also “listen” to generic topics, and tasks can notify those topics as follows:
handlers: - name: restart memcached service: name=memcached state=restarted listen: "restart web services" - name: restart apache service: name=apache state=restarted listen: "restart web services" tasks: - name: restart everything command: echo "this task will restart the web services" notify: "restart web services"
This use makes it much easier to trigger multiple handlers. It also decouples handlers from their names, making it easier to share handlers among playbooks and roles
Specifically to the question, this should work:
- name: Check if restarted shell: check_is_started.sh register: result listen: Restart processes - name: Restart conditionally step 2 service: name=service state=restarted when: result listen: Restart processes
and in the task, notify handlers via 'Restart processes'
http://docs.ansible.com/ansible/playbooks_intro.html#handlers-running-operations-on-change
In your handler file, chain the different steps together using notify.
- name: Restart conditionally debug: msg=Step1 changed_when: True notify: Restart conditionally step 2 - name: Restart conditionally step 2 debug: msg=Step2 changed_when: True notify: Restart conditionally step 3 - name: Restart conditionally step 3 debug: msg=Step3
Then refer to it from a task with notify: Restart conditionally
.
Note that you can only notify to handlers below the current one. So for example, Restart conditionally step 2
can't notify Restart conditionally
.
Source: #ansible at irc.freenode.net. I'm unsure whether this will continue to work in the future as it's not mentioned as a feature in the official documentation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With