Обработка ошибок в плейбуках
- Игнорирование неудачных команд
- Сброс недоступных хостов
- Обработчики и ошибки
- Управление определением ошибки
- Переопределение результата "изменено"
- Прерывание плейбука
- Использование блоков
Ansible обычно имеет значения по умолчанию, которые проверяют коды возврата команд и модулей и выполняет быстрое завершение — принудительно обрабатывает ошибку, если вы не решите иначе.
Иногда команда, возвращающая значение, отличное от 0, не является ошибкой. Иногда команде не всегда нужно сообщать, что она «изменила» удаленную систему. Этот раздел описывает, как изменить стандартное поведение Ansible для определенных задач, чтобы поведение вывода и обработки ошибок соответствовало вашим потребностям.
Игнорирование неудачных команд
Обычно плейбуки прекращают выполнение дальнейших шагов на хосте, на котором задача завершилась ошибкой. Однако иногда нужно продолжить. Для этого напишите задачу, которая выглядит так:
- name: this will not be counted as a failure command: /bin/false ignore_errors: yes
Обратите внимание, что указанная система управляет только значением возврата ошибки конкретной задачи, поэтому, если используется неопределенная переменная или синтаксическая ошибка, все равно будет выдаваться ошибка, которую пользователи должны будут обработать. Обратите внимание, что это не предотвратит ошибки при подключении или выполнении. Эта функция работает только в том случае, если задача должна быть выполнена и вернуть значение «ошибка».
Сброс недоступных хостов
Новое в версии 2.2.
Ошибки подключения устанавливают хосты как «НЕДОСТУПНЫЕ», что удаляет их из списка активных хостов для выполнения. Чтобы восстановиться после этих проблем, можно использовать meta: clear_host_errors для повторной активации всех хостов, которые в данный момент помечены как недоступные, чтобы последующие задачи могли снова их использовать.
Обработчики и ошибки
Когда задача завершается с ошибкой на хосте, обработчики, которые ранее были уведомлены, не будут запущены на этом хосте. Это может привести к ситуациям, когда несвязанная ошибка может оставить хост в неожиданном состоянии. Например, задача может обновить файл конфигурации и уведомить обработчик о перезапуске некоторой службы. Если впоследствии в том же плейбуке задача завершится ошибкой, служба не будет перезапущена, несмотря на изменение конфигурации.
Вы можете изменить это поведение с помощью команды --force-handlers в командной строке, включив force_handlers: True в плейбуке или force_handlers = True в ansible.cfg. Принудительное выполнение обработчиков приведет к их запуску при уведомлении, даже если задача на этом хосте завершится ошибкой. (Обратите внимание, что некоторые ошибки все еще могут помешать запуску обработчика, например, если хост станет недоступным.)
Управление определением ошибки
Ansible позволяет определить, что означает «ошибка» в каждой задаче, используя условное выражение failed_when. Как и во всех условных выражениях в Ansible, списки из нескольких failed_when условий объединяются с неявным and, что означает, что задача завершается с ошибкой только тогда, когда все условия выполнены. Если вы хотите вызвать ошибку, когда выполнено любое из условий, вы должны определить условия в строке с явным оператором or.
Вы можете проверить ошибку, выполнив поиск слова или фразы в выводе команды:
- name: Fail task when the command error output prints FAILED command: /usr/bin/example-command -x -y -z register: command_result failed_when: "'FAILED' in command_result.stderr"
или на основе кода возврата:
- name: Fail task when both files are identical raw: diff foo/file1 bar/file2 register: diff_cmd failed_when: diff_cmd.rc == 0 or diff_cmd.rc >= 2
В предыдущих версиях Ansible это можно было сделать следующим образом:
- name: this command prints FAILED when it fails
command: /usr/bin/example-command -x -y -z
register: command_result
ignore_errors: True
- name: fail the play if the previous command did not succeed
fail:
msg: "the command failed"
when: "'FAILED' in command_result.stderr"
Вы также можете объединить несколько условий для определения ошибки. Эта задача завершится ошибкой, если оба условия истинны:
- name: Check if a file exists in temp and fail task if it does
command: ls /tmp/this_should_not_be_here
register: result
failed_when:
- result.rc == 0
- '"No such" not in result.stdout'
Если вы хотите, чтобы задача завершилась ошибкой, когда выполнено только одно условие, измените определение failed_when на:
failed_when: result.rc == 0 or "No such" not in result.stdout
Если у вас слишком много условий для удобного размещения в одной строке, вы можете разбить их на несколько строк YAML с >.
- name: example of many failed_when conditions with OR
shell: "./myBinary"
register: ret
failed_when: >
("No such file or directory" in ret.stdout) or
(ret.stderr != '') or
(ret.rc == 10)
Переопределение результата "изменено"
При выполнении оболочки/команды или другого модуля, как правило, сообщается о статусе «изменено» на основе того, полагает ли он, что он повлиял на состояние машины.
Иногда, основываясь на коде возврата или выводе, вы знаете, что изменений не было, и хотите переопределить результат «изменено», чтобы он не отображался в отчете или не вызывал срабатывание обработчиков:
tasks:
- shell: /usr/bin/billybass --mode="take me to the river"
register: bass_result
changed_when: "bass_result.rc != 2"
# this will never report 'changed' status
- shell: wall 'beep'
changed_when: False
Вы также можете объединить несколько условий для переопределения результата «изменено»:
- command: /bin/fake_command
register: result
ignore_errors: True
changed_when:
- '"ERROR" in result.stderr'
- result.rc == 2
Прерывание плейбука
Иногда желательно прервать весь плейбук при ошибке, а не просто пропускать оставшиеся задачи для хоста.
Параметр плейбука any_errors_fatal помечает все хосты как ошибочные, если хотя бы один из них завершается ошибкой, вызывая немедленное прерывание:
- hosts: somehosts
any_errors_fatal: true
roles:
- myrole
Для более точного управления max_fail_percentage можно использовать для прерывания выполнения после того, как определенный процент хостов завершился с ошибкой.
Использование блоков
Большинство того, что можно применить к одной задаче (за исключением циклов), можно применить на уровне блоков, что также значительно упрощает установку данных или директив, общих для задач. Блоки также вводят возможность обработки ошибок аналогично исключениям в большинстве языков программирования. Блоки обрабатывают только статус «ошибка» задачи. Ошибки, связанные с неправильной задачей или недоступным хостом, не являются «восстанавливаемыми» ошибками:
tasks:
- name: Handle the error
block:
- debug:
msg: 'I execute normally'
- name: i force a failure
command: /bin/false
- debug:
msg: 'I never execute, due to the above task failing, :-('
rescue:
- debug:
msg: 'I caught an error, can do stuff here to fix it, :-)'
Это «отменит» статус ошибки внешней задачи block для выполнения, и плейбук продолжит выполнение так, как будто он завершился успешно. Дополнительные примеры см. в разделе обработка ошибок в блоках.
См. также
- Работа с плейбуками
- Введение в плейбуки
- Рекомендации по практике
- Рекомендации по практике в плейбуках
- Условные выражения
- Условные операторы в плейбуках
- Использование переменных
- Все о переменных
- Список рассылки пользователей
- Есть вопрос? Загляните в группу Google!
- irc.freenode.net
- #ansible IRC-чат-канал
© 2012–2018 Michael DeHaan
© 2018–2019 Red Hat, Inc.
Licensed under the GNU General Public License version 3.
https://docs.ansible.com/ansible/2.8/user_guide/playbooks_error_handling.html