Ansible check mode: что реально проверяет dry run и чего он не видит
Playbook прошёл --check без ошибок, но обычный запуск упал на команде настройки. В check mode эта команда могла вообще не выполняться. Поэтому результат dry run надо читать по задачам: что реально проверено, что только спрогнозировано и что пропущено.
Ansible передаёт модулям признак check mode. Модуль с поддержкой может сравнить текущее и желаемое состояние и сообщить would change без записи. Модуль без такой поддержки обычно пропускает действие. Это полезная предварительная проверка, но её результат не равен выполнению всего плана в отдельной копии системы.
Две версии одного файла
Создайте на локальном Linux-стенде /tmp/latorn-check-mode.conf с содержимым mode=old. Следующий demo.yml собирается заменить строку на mode=new и затем читает фактический файл. Чтение специально разрешено в обычном режиме, поскольку cat не меняет содержимое.
- name: Compare prediction with the real file
hosts: localhost
connection: local
gather_facts: false
tasks:
- name: Predict or write the new configuration
ansible.builtin.copy:
content: "mode=new\n"
dest: /tmp/latorn-check-mode.conf
mode: '0600'
- name: Read the file actually present on disk
ansible.builtin.command:
argv: [cat, /tmp/latorn-check-mode.conf]
check_mode: false
changed_when: false
register: actual_file
- name: Display actual file content
ansible.builtin.debug:
var: actual_file.stdout
printf 'mode=old\n' > /tmp/latorn-check-mode.conf ansible-playbook -i localhost, demo.yml --check --diff ansible-playbook -i localhost, demo.yml ansible-playbook -i localhost, demo.yml --check --diff
Первый check должен показать предполагаемую замену old на new, но cat прочитает mode=old: записи не было. Обычный запуск выполнит замену, и чтение увидит mode=new. Последний check уже не должен предсказывать новое изменение. Так видно, почему зависимая проверка содержимого после виртуальной записи способна дать неожиданный результат.
Check_mode false выполняет задачу по-настоящему
В примере исключение безопасно по назначению: cat только читает учебный файл. Но check_mode: false на shell-установке пакета или удалении данных разрешит реальное изменение даже при глобальном --check. Перед использованием dry run найдите такие исключения во всём playbook и подключённых ролях.
Обратное значение check_mode: true заставляет отдельную задачу моделировать действие и при обычном запуске. Это может быть полезно для предварительной оценки, но не должно случайно остаться на обязательной записи конфигурации.
Пропущенная command не подтверждает команду
Обычный command без creates/removes не имеет универсального способа предсказать побочные эффекты и часто пропускается в check mode. Наличие этих параметров позволяет оценить необходимость запуска по файловому признаку, но не проверяет успешность самой команды. Ошибка пути к исполняемому файлу или отсутствие разрешений могут обнаружиться только при настоящем выполнении.
Если последующая задача использует register от пропущенной команды, у результата может не быть ожидаемого stdout. Условие вида result.stdout == нужное значение потребует учёта пропуска. Не подставляйте заранее ожидаемый результат ради зелёного check: лучше явно отделить прогноз состояния от проверки, которой нужны реально созданные данные.
Diff помогает там, где его безопасно читать
Diff mode показывает различия поддерживаемых модулей, а не полный журнал всех будущих изменений системы. Для шаблона он полезен: можно увидеть неверный порт или неожиданное удаление строки до применения.
Если файл содержит секреты, diff способен раскрыть старое и новое значение. Для такой задачи задайте diff: false и продумайте no_log. Проверять секретный шаблон удобнее на фиктивных значениях в стенде, сохраняя тот же формат, чем выводить рабочее содержимое в CI.
Завершённая проверка включает синтаксис, осмысленный check/diff и реальное выполнение на ограниченном стенде. В отчёте различайте эти уровни: check показал ожидаемый diff, команда пропущена, стендовый запуск подтвердил действие. Тогда dry run помогает принять решение, а его зелёный статус не скрывает непроверенные части процесса.
Ещё по теме
- Ansible взял не ту переменную: разбираем inventory, group_vars и host_vars
- Ansible --tags пропускает нужные задачи: include_tasks и import_tasks
Продолжить изучение
Хотите собрать настройку серверов в повторяемый процесс? Inventory, роли, шаблоны и обновление сервисов входят в программу «Ansible: автоматизация инфраструктуры».
Продолжить на практике
- Ansible: автоматизация инфраструктуры ↗
Настраивайте серверы воспроизводимо: inventory, playbooks, роли, шаблоны и секреты. Соберите автоматизацию для нескольких окружений, проверьте повторный запуск и обновляйте сервисы управляемо.
