Написание идемпотентного плейбука

AnsibleBeginner
Практиковаться сейчас

Введение

Несколько связанных разовых команд легче повторять и проверять, если сохранить их в плейбуке. Полезный плейбук описывает стабильное желаемое состояние и даёт наблюдаемые результаты на каждом нужном целевом узле.

Вы напишете небольшой плейбук YAML с модулями file и copy, примените его к двум узлам SSH и проверите созданные файлы и повторный запуск без изменений. Эта лабораторная работа знакомит с plays, задачами и идемпотентностью без переменных, циклов и ролей.

Напишите плейбук в YAML

На этом шаге вы объедините уже отработанные модули file и copy в многократно используемый плейбук.

Перейдите в проект в терминале:

cd /home/labex/project

Плейбук — список plays в формате YAML. Каждый play связывает шаблон хостов с упорядоченным списком задач. Каждая задача указывает модуль и его аргументы. Метки name помогают людям читать вывод; сами по себе они не создают конфигурацию.

YAML использует отступы для вложенности данных. Используйте пробелы, а не табуляцию. Начальный - обозначает элемент списка, а двоеточие вводит значение ключа. Здесь tasks содержит две задачи модулей. Права в кавычках, например "0750", остаются строками прав. gather_facts: false пропускает автоматический сбор фактов, поскольку задачи с фиксированным состоянием не используют факты.

Создайте файл с here-document в кавычках, как вы делали ранее. Скопируйте текст до последней строки EOF включительно:

cat > workspace.yml <<'EOF'
- name: Prepare managed workspaces
  hosts: all
  gather_facts: false
  tasks:
    - name: Create the workspace directory
      ansible.builtin.file:
        path: /home/automation/workspace
        state: directory
        mode: "0750"

    - name: Write the workspace notice
      ansible.builtin.copy:
        dest: /home/automation/workspace/README.txt
        content: "Workspace managed by Ansible\n"
        mode: "0640"
EOF

Первая задача объявляет каталог. Вторая использует аргумент copy content, чтобы передать буквальный текст напрямую вместо чтения исходного файла src на управляющем узле. Строка YAML в двойных кавычках интерпретирует \n как завершающий перевод строки. Фиксированное содержимое делает повторный запуск стабильным; не добавляйте изменяющуюся временную метку.

В play используется hosts: all, что означает оба предоставленных узла SSH. Обычные задачи выполняются от automation, поэтому его домашний каталог доступен для записи без become.

ansible-playbook выполняет файлы плейбуков. Сначала используйте --syntax-check для проверки структуры без применения задач:

ansible-playbook workspace.yml --syntax-check

Ожидайте строку идентификации плейбука и отсутствие ошибок синтаксического анализа. Одна лишь проверка синтаксиса не подтверждает удалённое соединение или правильность итоговых файлов.

Предварительно просмотрите выбор хостов play через --list-hosts:

ansible-playbook workspace.yml --list-hosts

Play должен перечислять web1 и web2. Пустой список не является работоспособным плейбуком для двух хостов.

Примените желаемое состояние

На этом шаге вы запустите плейбук и изучите его фактические удалённые результаты.

Выполните файл из проекта, чтобы были выбраны его конфигурация и инвентарь:

ansible-playbook workspace.yml

Ansible выводит имя каждого play и задачи, затем PLAY RECAP. В новом окружении две задачи должны изменить каждый хост:

web1 : ok=2 changed=2 unreachable=0 failed=0 ...
web2 : ok=2 changed=2 unreachable=0 failed=0 ...

Пробелы и порядок хостов могут отличаться. ok считает успешные задачи, changed — задачи, которым потребовались изменения, а unreachable/failed должны оба равняться нулю. Одно лишь успешное имя задачи не подтверждает требуемые байты или права файла.

Прочитайте каждое удалённое уведомление с помощью модуля command ad hoc:

ansible all -m ansible.builtin.command -a 'cat /home/automation/workspace/README.txt'

Оба значения stdout должны показывать Workspace managed by Ansible. Запрос command, который только читает данные, всё равно может сообщать CHANGED; результаты file/copy плейбука описывают объявленное состояние. Управляемый каталог имеет права 0750, уведомление — 0640, и оба принадлежат automation.

Проверьте идемпотентное приведение к состоянию

На этом шаге вы повторите плейбук и убедитесь, что соответствующее состояние не требует дополнительных изменений.

Идемпотентность означает, что повторное применение одного желаемого состояния не создаёт ненужных изменений после его достижения. Запустите тот же плейбук ещё раз:

ansible-playbook workspace.yml

Ожидайте итог для каждого целевого узла с ok=2, changed=0, unreachable=0 и failed=0. Оба файла остаются на месте и соответствуют требованиям. Изменяющаяся временная метка или безусловная общая команда нарушили бы этот стабильный результат.

--check запрашивает предварительный просмотр: поддерживающие его модули прогнозируют изменения, не применяя их. И file, и copy поддерживают этот порядок работы. Предварительно проверьте плейбук после достижения состояния:

ansible-playbook workspace.yml --check

Снова ожидайте ноль изменений для обоих хостов. Предварительный просмотр не заменяет первое настоящее выполнение или изучение фактического состояния. Здесь он подтверждает, что уже созданные рабочие каталоги соответствуют объявлениям.

Сохраните плейбук для будущего использования. Не скрывайте изменения через changed_when и не принуждайте задачи выполняться вне режима проверки ради чистого итога; результат должен отражать фактическое соответствие состояния.

Резюме

Вы выразили выбор хостов и упорядоченные задачи модулей в YAML, проверили синтаксис и область целевых узлов и применили плейбук к двум настоящим управляемым узлам. Фактическое состояние файлов соответствовало требованиям, второй настоящий запуск не внёс дополнительных изменений, а режим проверки без записи не обнаружил ожидающих изменений.