Предыдущий урок: Ansible практика – урок №7: Копирование файлов на удаленный сервер.
В прошлом уроке мы добавили таск для перезапуска MariaDB, такой же таск есть для Firewalld. Проблема в том, что в таком виде, перезапуск сервиса осуществляется при любой раскатке, даже когда изменений в настройках сервиса не произошло.
Зачем нужен notify и handler?
notify – параметр, присваиваемый текущей задаче, указывающий на используемый handler.
handler – вспомогательная задача, которую Ansible исполнит, если текущая задача произвела изменения на управляемом хосте.
Использование notify и handler
Внесем изменения в роли, работающие с сервисами MariaDB и Firewalld соответственно.
Шаг 1: Создаем handler
Создадим новые директории, с названием handlers, в каждой из ролей:
[root@Control-Node ansible]# mkdir roles/mariadb/handlers roles/firewalld/handlers
[root@Control-Node ansible]#
Создадим файл roles/mariadb/handlers/main.yml с содержанием:
---
- name: restart_mariadb
ansible.builtin.service:
name: mariadb
state: restarted
Тут имя хендлера restart_mariadb.
Второй файл roles/firewalld/handlers/main.yml:
---
- name: restart_firewalld
ansible.builtin.service:
name: firewalld
state: restarted
Имя хендлера – restart_firewalld.
Хендлеры готовы.
Шаг 2: Присваиваем handler
Отредактируем роли, убрав из них таски по перезапуску сервисов, и укажем хендлеры.
После редактирования файл roles/mariadb/tasks/main.yml выглядит так:
---
- name: "Role: MariaDB | Block: Installation"
tags:
- installation
- mariadb
block:
- name: "Install MariaDB on CentOS"
ansible.builtin.dnf:
name: mariadb-server
state: latest
when: ansible_distribution == "CentOS"
- name: "Install MariaDB on Ubuntu"
ansible.builtin.apt:
name: mariadb-server
state: latest
when: ansible_distribution == "Ubuntu"
- name: "Ensure MariaDB is started and enabled"
ansible.builtin.service:
name: mariadb
state: started
enabled: true
tags:
- start
- mariadb
- name: "Role: MariaDB | Block: custom config"
notify: restart_mariadb
tags:
- mariadb
block:
- name: "Copy custom config file to CentOS"
ansible.builtin.copy:
src: logs.cnf
dest: /etc/my.cnf.d/logs.cnf
owner: root
group: root
mode: '0644'
when: ansible_distribution == "CentOS"
- name: "Copy custom config file to Ubuntu"
ansible.builtin.copy:
src: logs.cnf
dest: /etc/mysql/mariadb.conf.d/logs.cnf
owner: root
group: root
mode: '0644'
when: ansible_distribution == "Ubuntu"
С помощью notify мы присвоили хендлер restart_mariadb блоку “Role: MariaDB | Block: custom config”.
Модифицированный файл roles/firewalld/tasks/main.yml:
---
- name: "Role: Firewalld | Block: Installation"
tags:
- installation
- firewalld
block:
- name: "Install firewalld on CentOS"
ansible.builtin.dnf:
name: firewalld
state: latest
when: ansible_distribution == "CentOS"
- name: "Install firewalld on Ubuntu"
ansible.builtin.apt:
name: firewalld
state: latest
when: ansible_distribution == "Ubuntu"
- name: "Ensure Firewalld is started and enabled"
ansible.builtin.service:
name: firewalld
state: started
enabled: yes
tags:
- start
- firewalld
- name: "Role: Firewalld | Block: allow services"
notify: restart_firewalld
tags:
- firewalld
block:
- name: "Open SSH service permanently in public zone"
ansible.posix.firewalld:
zone: public
service: ssh
permanent: true
state: enabled
- name: "Open HTTP service permanently in public zone"
ansible.posix.firewalld:
zone: public
service: http
permanent: true
state: enabled
- name: "Open HTTPS service permanently in public zone"
ansible.posix.firewalld:
zone: public
service: https
permanent: true
state: enabled
Тут хендлер restart_firewalld добавлен блоку “Role: Firewalld | Block: allow services”.
Шаг 3: Проверяем плейбук
Запустим Ansible и посмотрим, как отработают хендлеры. Чтобы исключить роли и задачи, которые не претерпели изменений в данном уроке, используем комбинацию включенных и исключенных тегов:
[root@Control-Node ansible]# ansible-playbook install_lemp.yml --tags mariadb,firewalld --skip-tags installation
PLAY [all] ******************************************************************************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************************************************************************
ok: [Managed-Node-2]
ok: [Managed-Node-1]
ok: [Managed-Node-3]
TASK [mariadb : Ensure MariaDB is started and enabled] **********************************************************************************************************************************************
ok: [Managed-Node-1]
ok: [Managed-Node-3]
ok: [Managed-Node-2]
TASK [mariadb : Copy custom config file to CentOS] **************************************************************************************************************************************************
skipping: [Managed-Node-3]
ok: [Managed-Node-2]
ok: [Managed-Node-1]
TASK [mariadb : Copy custom config file to Ubuntu] **************************************************************************************************************************************************
skipping: [Managed-Node-1]
skipping: [Managed-Node-2]
ok: [Managed-Node-3]
TASK [firewalld : Ensure Firewalld is started and enabled] ******************************************************************************************************************************************
ok: [Managed-Node-1]
ok: [Managed-Node-2]
ok: [Managed-Node-3]
TASK [firewalld : Open SSH service permanently in public zone] **************************************************************************************************************************************
ok: [Managed-Node-3]
ok: [Managed-Node-1]
ok: [Managed-Node-2]
TASK [firewalld : Open HTTP service permanently in public zone] *************************************************************************************************************************************
ok: [Managed-Node-1]
ok: [Managed-Node-3]
ok: [Managed-Node-2]
TASK [firewalld : Open HTTPS service permanently in public zone] ************************************************************************************************************************************
ok: [Managed-Node-3]
ok: [Managed-Node-1]
ok: [Managed-Node-2]
PLAY RECAP ******************************************************************************************************************************************************************************************
Managed-Node-1 : ok=7 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
Managed-Node-2 : ok=7 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
Managed-Node-3 : ok=7 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
[root@Control-Node ansible]#
Ansible отработал без ошибок, но мы нигде не видим работу хэндлеров. Это потому, что задачи, к которым прикреплены хендлеры, не внесли никаких изменений, а значит и причин вызывать хендлер тоже нет.
Давайте подкинем Ansible работенку, зайдем на какую-нибудь Managed Node и и выведем систему из соответствия плейбуку.
Удалим файл /etc/my.cnf.d/logs.cnf:
[root@Managed-Node-1 ~]# rm -f /etc/my.cnf.d/logs.cnf
[root@Managed-Node-1 ~]#
И уберем http из разрешенных сервисов Firewalld:
[root@Managed-Node-1 ~]# firewall-cmd --zone=public --remove-service=http --permanent
success
[root@Managed-Node-1 ~]#
Теперь Ansible будет чем заняться. Повторим раскатку, только ограничимся хостом, на котором мы делали изменения:
[root@Control-Node ansible]# ansible-playbook install_lemp.yml --tags mariadb,firewalld --skip-tags installation --limit Managed-Node-1
PLAY [all] ******************************************************************************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************************************************************************
ok: [Managed-Node-1]
TASK [mariadb : Ensure MariaDB is started and enabled] **********************************************************************************************************************************************
ok: [Managed-Node-1]
TASK [mariadb : Copy custom config file to CentOS] **************************************************************************************************************************************************
changed: [Managed-Node-1]
TASK [mariadb : Copy custom config file to Ubuntu] **************************************************************************************************************************************************
skipping: [Managed-Node-1]
TASK [firewalld : Ensure Firewalld is started and enabled] ******************************************************************************************************************************************
ok: [Managed-Node-1]
TASK [firewalld : Open SSH service permanently in public zone] **************************************************************************************************************************************
ok: [Managed-Node-1]
TASK [firewalld : Open HTTP service permanently in public zone] *************************************************************************************************************************************
changed: [Managed-Node-1]
TASK [firewalld : Open HTTPS service permanently in public zone] ************************************************************************************************************************************
ok: [Managed-Node-1]
RUNNING HANDLER [mariadb : restart_mariadb] *********************************************************************************************************************************************************
changed: [Managed-Node-1]
RUNNING HANDLER [firewalld : restart_firewalld] *****************************************************************************************************************************************************
changed: [Managed-Node-1]
PLAY RECAP ******************************************************************************************************************************************************************************************
Managed-Node-1 : ok=9 changed=4 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
[root@Control-Node ansible]#
На этот раз задачи [mariadb : Copy custom config file to CentOS] и [firewalld : Open HTTP service permanently in public zone] закончились с результатом changed. Что вызвало срабатывание хендлеров (RUNNING HANDLER).
Ansible запускает хендлеры в конце, после того как все таски исполнены. И если несколько задач вызывают один и тот же хендлер, он будет исполнен один раз, исключая избыточные вызовы.
Итоги:
Мы рассмотрели, как в Ansible работают хендлеры. Связка notify – handler отлично позволяет контролировать состояние сервисов и реагировать на внесенные изменения.
Следующий урок: Ansible практика – урок №9: Как использовать переменные в playbook.