Блоки
Блоки создают логические группы задач. Блоки также позволяют обрабатывать ошибки задач, подобно обработке исключений во многих языках программирования.
Группировка задач с помощью блоков
Все задачи в блоке наследуют директивы, применённые на уровне блока. Большинство параметров, которые можно применить к отдельной задаче (за исключением циклов), можно применить и на уровне блока, поэтому блоки значительно упрощают настройку данных или директив, общих для задач. Директива не влияет на сам блок — её наследуют только задачи, заключённые в блок. Например, инструкция when применяется к задачам внутри блока, а не к самому блоку.
tasks:
- name: Install, configure, and start Apache
when: ansible_facts['distribution'] == 'CentOS'
block:
- name: Install httpd and memcached
ansible.builtin.yum:
name:
- httpd
- memcached
state: present
- name: Apply the foo config template
ansible.builtin.template:
src: templates/src.j2
dest: /etc/foo.conf
- name: Start service bar and enable it
ansible.builtin.service:
name: bar
state: started
enabled: True
become: true
become_user: root
ignore_errors: true
В приведённом выше примере условие ‘when’ будет проверяться перед запуском Ansible каждой из трёх задач в блоке. Все три задачи также наследуют директивы повышения привилегий и выполняются от имени пользователя root. Наконец, ignore_errors: true гарантирует, что Ansible продолжит выполнение плейбука, даже если некоторые задачи завершатся с ошибкой.
Примечание
Все задачи в блоке, в том числе включённые с помощью include_role, наследуют директивы, применённые на уровне блока.
Имена блоков доступны начиная с Ansible 2.3. Мы рекомендуем задавать имена для всех задач — внутри блоков и вне их, — чтобы лучше видеть, какие задачи выполняются при запуске плейбука.
Обработка ошибок с помощью блоков
С помощью блоков с секциями rescue и always можно управлять реакцией Ansible на ошибки задач.
Примечание
Ошибки, вызванные неверными определениями задач и недоступными хостами, не запускают секции rescue или always блока.
В блоках восстановления указываются задачи, которые необходимо выполнить, если одна из предыдущих задач в блоке завершилась с ошибкой. Этот подход похож на обработку исключений во многих языках программирования. Ansible запускает блоки восстановления только после того, как задача возвращает состояние ‘failed’.
tasks:
- name: Handle the error
block:
- name: Print a message
ansible.builtin.debug:
msg: 'I execute normally'
- name: Force a failure
ansible.builtin.command: /bin/false
- name: Never print this
ansible.builtin.debug:
msg: 'I never execute, due to the above task failing, :-('
rescue:
- name: Print when errors
ansible.builtin.debug:
msg: 'I caught an error, can do stuff here to fix it, :-)'
В блок также можно добавить секцию always. Задачи в секции always выполняются независимо от состояния задач в предыдущем блоке.
tasks:
- name: Always do X
block:
- name: Print a message
ansible.builtin.debug:
msg: 'I execute normally'
- name: Force a failure
ansible.builtin.command: /bin/false
- name: Never print this
ansible.builtin.debug:
msg: 'I never execute :-('
always:
- name: Always do this
ansible.builtin.debug:
msg: "This always executes, :-)"
Вместе эти элементы позволяют реализовать сложную обработку ошибок.
tasks:
- name: Attempt and graceful roll back demo
block:
- name: Print a message
ansible.builtin.debug:
msg: 'I execute normally'
- name: Force a failure
ansible.builtin.command: /bin/false
- name: Never print this
ansible.builtin.debug:
msg: 'I never execute, due to the above task failing, :-('
rescue:
- name: Print when errors
ansible.builtin.debug:
msg: 'I caught an error'
- name: Force a failure in middle of recovery! >:-)
ansible.builtin.command: /bin/false
- name: Never print this
ansible.builtin.debug:
msg: 'I also never execute :-('
always:
- name: Always do this
ansible.builtin.debug:
msg: "This always executes"
Задачи в секции block выполняются в обычном режиме. Если какая-либо задача в блоке возвращает failed, в секции rescue выполняются задачи для восстановления после ошибки. Секция always запускается независимо от результатов секций block и rescue.
Если в блоке возникает ошибка, а задача восстановления завершается успешно, Ansible отменяет статус ошибки исходной задачи для текущего запуска и продолжает выполнение плейбука так, как если бы исходная задача завершилась успешно. Задача восстановления считается успешной и не активирует конфигурации max_fail_percentage или any_errors_fatal. Однако в статистике плейбука Ansible по-прежнему сообщает об ошибке.
В задаче восстановления можно использовать блоки с flush_handlers, чтобы гарантировать запуск всех обработчиков даже в случае ошибки:
tasks:
- name: Attempt and graceful roll back demo
block:
- name: Print a message
ansible.builtin.debug:
msg: 'I execute normally'
changed_when: true
notify: Run me even after an error
- name: Force a failure
ansible.builtin.command: /bin/false
rescue:
- name: Make sure all handlers run
meta: flush_handlers
handlers:
- name: Run me even after an error
ansible.builtin.debug:
msg: 'This handler runs even on error'
Добавлено в версии 2.1.
Ansible предоставляет несколько переменных для задач в части rescue блока:
- ansible_failed_task
-
Задача, которая вернула состояние ‘failed’ и запустила восстановление. Например, чтобы получить её имя, используйте
ansible_failed_task.name. - ansible_failed_result
-
Сохранённый результат выполнения задачи, которая завершилась с ошибкой и запустила восстановление. Это соответствует использованию этой переменной в ключевом слове
register.
Эти переменные можно проверить в секции rescue:
tasks:
- name: Attempt and graceful roll back demo
block:
- name: Do Something
ansible.builtin.shell: grep $(whoami) /etc/hosts
- name: Force a failure, if previous one succeeds
ansible.builtin.command: /bin/false
rescue:
- name: All is good if the first task failed
when: ansible_failed_task.name == 'Do Something'
ansible.builtin.debug:
msg: All is good, ignore error as grep could not find 'me' in hosts
- name: All is good if the second task failed
when: "'/bin/false' in ansible_failed_result.cmd | d([])"
ansible.builtin.fail:
msg: It is still false!!!
Примечание
В ansible-core 2.14 и более поздних версиях обе переменные передаются из внутреннего блока во внешнюю часть rescue при вложении блоков.
См. также
- Плейбуки Ansible
-
Введение в плейбуки
- Роли
-
Организация плейбука с помощью ролей
- Общение
-
Есть вопросы? Нужна помощь? Хотите поделиться идеями? Посетите руководство по общению Ansible
© 2012–2018 Michael DeHaan
© 2018–2025 Red Hat, Inc.
Licensed under the GNU General Public License version 3.
https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_blocks.html