Rolling restart with ansible handlers
Ansible 2.9.0 introduced the throttle
keyword, which can be used at the task, block, or play level to limit the number of workers (up to the specified forks or serial setting) allowed.
For example, this can be used to restart nodes in a database cluster one by one:
- name: Restart MySQL
throttle: 1
service:
name: mysql
state: restarted
Currently it's not possible. There is an issue oppened for this.
Handlers are just tasks that Ansible will run at the end of a play if necessary. Given that they're implicitly added to the end of your play, they're going to be treated the same as any other tasks as far as parameters like serial
go. Unfortunately this means that without a feature request that the Ansible developers accept you're unlikely to see a change in the behavior of serial
to support what you're trying to do.
I know you mentioned wanting to avoid hacks, but that's going to be the only way you can do something like this at this point. It shouldn't be too difficult to set up something that's not a major hack, like creating a temporary file to flag the restart:
- hosts: some_hosts
name: install service
serial: 10
- handlers:
- name: schedule restart
command: touch /tmp/restart_flag
- tasks:
- name: install service
action: whatever...
notify: schedule restart
- hosts: some_hosts
name: restart service
serial: 2
- handlers:
- name: perform restart
service: name=foo state=restarted
- tasks:
- name: Delete /tmp/restart_flag. Restart service if file is deleted.
file: path=/tmp/restart_flag state=absent
notify: perform restart