Короткий ответ
Handler — это задача, которая запускается только тогда, когда её явно "уведомила" (notify) другая задача, помеченная как changed, и выполняется один раз в конце play даже если уведомлений было несколько; это позволяет перезапускать сервис только при реальном изменении конфигурации, а не при каждом запуске playbook.
Как это работает подробнее
задача с notify: <имя handler> добавляет handler в очередь только если её статус — changed; в конце play (или раньше, если явно вызван flush_handlers) Ansible выполняет каждый уникальный handler из очереди ровно один раз, независимо от того, сколько задач его вызвали.
Пример кода
playbook.yml
tasks:
- name: Обновить конфиг nginx
ansible.builtin.template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Перезапустить nginx
handlers:
- name: Перезапустить nginx
ansible.builtin.service:
name: nginx
state: restartedЧто использовать на практике
- Практика. типичный паттерн — задача шаблонирования конфига (
template) уведомляет handler "restart service"; если конфиг не изменился, handler не сработает, и сервис не будет перезапущен без необходимости, что снижает downtime при частых прогонах playbook.
Подводные камни
- Ошибка. ставить обычную задачу
service: state=restartedсразу после задачи шаблонирования без notify — тогда сервис будет перезапускаться при каждом запуске playbook независимо от того, изменился ли конфиг; забывать, что handlers по умолчанию выполняются в конце play, а не сразу в месте notify.