Ответ
В ролях Ansible я активно использую хендлеры для выполнения задач только при изменении состояния системы. Например, перезапуск службы только после изменения её конфигурационного файла. Хендлеры объявляются в handlers/main.yml и вызываются через notify в задачах.
Шаблоны Jinja2 применяю для динамической генерации конфигурационных файлов с подстановкой переменных, фактов Ansible и результатов выполнения задач.
Пример использования:
# tasks/main.yml
- name: Deploy Nginx configuration
ansible.builtin.template:
src: templates/nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: restart nginx
# handlers/main.yml
- name: restart nginx
ansible.builtin.service:
name: nginx
state: restarted
Шаблон nginx.conf.j2:
server {
listen {{ nginx_port | default(80) }};
server_name {{ server_name }};
root {{ web_root }};
}
Ключевые особенности в моём опыте:
- Хендлеры выполняются один раз в конце плейбука, даже при нескольких уведомлениях.
- Для принудительного выполнения хендлеров в середине плейбука использовал
meta: flush_handlers. - В шаблонах использовал фильтры Jinja2 (
default,to_json), условия (if/else) и циклы (for). - Переменные для шаблонов брал из
vars/,defaults/,group_vars/, а также изansible_facts. - Для сложной логики использовал кастомные фильтры и lookup-плагины внутри шаблонов.