Handlers
- 2 mins read
Классический кейс (Один триггер — один хэндлер)
Самый частый вариант: конфиг изменился -> хэндлер перезапустил сервис. Если конфиг не менялся, шаг с перезапуском просто пропускается.
tasks:
- name: Кейс 1 — Меняем конфиг Nginx
copy:
src: nginx.conf
dest: /etc/nginx/nginx.conf
notify: Перезапустить Nginx # Имя должно строго совпадать с именем хэндлера
handlers:
- name: Перезапустить Nginx
systemd:
name: nginx
state: restarted
Один триггер вызывает цепочку хэндлеров (Список)
Если изменение одного файла требует совершить сразу несколько действий (например, сбросить кэш, а потом перезапустить сервис), в notify можно передать список.
tasks:
- name: Кейс 2 — Обновляем настройки приложения
template:
src: app.conf.j2
dest: /var/www/app.conf
notify:
- Очистить кэш приложения
- Перезапустить приложение
handlers:
- name: Очистить кэш приложения
file:
path: /var/www/cache/
state: absent
- name: Перезапустить приложение
systemd:
name: myapp
state: restarted
Несколько тасок вызывают один и тот же хэндлер
Если у тебя три разные таски меняют разные конфиги одного сервиса, они все могут вызывать один хэндлер. Ansible сообразит и выполнит его всего один раз в самом конце плейбука.
tasks:
- name: Кейс 3.1 — Настраиваем первый конфиг
copy: src=site.conf dest=/etc/nginx/conf.d/
notify: Перезапустить Nginx
- name: Кейс 3.2 — Настраиваем второй конфиг
copy: src=ssl.conf dest=/etc/nginx/conf.d/
notify: Перезапустить Nginx
handlers:
- name: Перезапустить Nginx
systemd:
name: nginx
state: restarted
Группировка через темы (Параметр listen)
Вместо того чтобы прописывать длинные имена хэндлеров, им можно дать один общий «канал связи» через listen. Таски шлют уведомление в этот канал, и все подписанные хэндлеры срабатывают.
tasks:
- name: Кейс 4 — Меняем настройки веб-сервера
copy: src=php.ini dest=/etc/php.ini
notify: "web_config_changed" # Шлем сигнал в канал
handlers:
- name: Перезапуск PHP
systemd: name=php-fpm state=restarted
listen: "web_config_changed" # Слушает канал
- name: Перезапуск Nginx
systemd: name=nginx state=restarted
listen: "web_config_changed" # Тоже слушает этот канал
Принудительный вызов хэндлеров прямо посреди плейбука (Flush Handlers)
По умолчанию Ansible копит все сигналы notify и выполняет хэндлеры в самом-самом конце плейбука. Но если тебе нужно, чтобы сервис перезапустился немедленно (например, потому что следующие таски будут делать к нему запросы), используется специальный модуль meta: flush_handlers.
tasks:
- name: Кейс 5.1 — Ставим и настраиваем базу данных
template: src=my.cnf.j2 dest=/etc/mysql/my.cnf
notify: Перезапустить MySQL
- name: Кейс 5.2 — Форсируем выполнение хэндлера прямо сейчас
meta: flush_handlers # Ansible прервется и перезапустит MySQL прямо тут
- name: Кейс 5.3 — Накатываем бэкап (база уже должна железно работать)
mysql_db: name=prod state=import target=/tmp/backup.sql