Почему command нарушает идемпотентность
Ловушка необработанных команд оболочки и способы её избежать.
«Почему command нарушает идемпотентность» — бесплатный урок Ansible Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Ansible Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Ansible Academy содержит 4 уроков всего.
command выполняется всегда
Модуль команд просто выполняет на хосте всё, что Вы ему передадите. Он не знает, как выглядит состояние «готово», поэтому выполняется каждый раз.
ansible.builtin.command: useradd deployВсегда changed
Поскольку команда не умеет проверять состояние, Ansible сообщает о статусе changed при каждом запуске, даже если команда фактически не сделала ничего нового.
changed: [web1]Повторный запуск может навредить
Хуже того, некоторые команды при повторном запуске завершаются с ошибкой или дублируют работу — например, useradd выдаёт ошибку, если пользователь уже существует.
Предпочитайте модуль, работающий с состоянием
Для пользователей вместо этого используйте модуль управления пользователями. Он проверяет существование учётной записи и создаёт её только при отсутствии, сохраняя идемпотентность.
ansible.builtin.user:
name: deploy
state: presentОбычно для этого есть модуль
Для большинства распространённых задач оболочки есть специальный модуль: для работы с файлами, копирования, изменения строк и git. Используйте их, чтобы Ansible мог сравнивать состояние и пропускать задачу, когда всё уже правильно.
Защитите команду с помощью creates
Если Вам необходимо использовать команду, добавьте creates. Ansible пропустит задачу, если этот путь уже существует, восстановив идемпотентность.
ansible.builtin.command: ./build.sh
args:
creates: /opt/app/builtИли защитите её с помощью removes
Зеркальный параметр для creates — removes: команда выполняется только в том случае, если указанный путь всё ещё существует. Это удобно для задач очистки.
ansible.builtin.command: rm /tmp/lock
args:
removes: /tmp/lockОграничьте команду с помощью when
Можно также обернуть команду в условие when, зависящее от зарегистрированной проверки, чтобы она выполнялась только при реальной необходимости.
Сообщите Ansible, что изменений не было
Установите для команды, доступной только для чтения, значение changed_when: false, чтобы Ansible не сообщал о статусе changed при каждом запуске.
ansible.builtin.command: cat /etc/hostname
changed_when: falseУ shell та же проблема
Модуль оболочки имеет тот же недостаток. Он выполняется через оболочку, поэтому тоже не является идемпотентным, если не защищать его таким же образом.
Используйте необработанные команды только в крайнем случае
Необработанная команда — это запасной выход, а не вариант по умолчанию. Каждая такая команда может незаметно нарушить идемпотентность, поэтому используйте её только тогда, когда не подходит ни один модуль.
Быстрая проверка
Вы использовали команду для запуска сценария сборки, и при каждом запуске она показывает changed.
Повторение
Модули команд и оболочки всегда выполняются и всегда сообщают changed. Предпочитайте настоящие модули или защищайте их с помощью creates, removes либо changed_when. 🛡️
Часто задаваемые вопросы
Урок «Почему command нарушает идемпотентность» бесплатный?
Да — полный текст урока «Почему command нарушает идемпотентность» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Ansible Academy, подпишись на CoddyKit PRO. Курс Ansible Academy содержит 4 уроков всего.
Чему я научусь в уроке «Почему command нарушает идемпотентность»?
Ловушка необработанных команд оболочки и способы её избежать. Ты практикуешь Ansible Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Ansible Academy?
Предыдущий опыт не требуется. Ansible Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Почему command нарушает идемпотентность»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Ansible Academy?
Да. Каждый урок Ansible Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Желаемое состояние вместо пошаговых скриптов
- Чтение changed и ok в выводе
- Почему command нарушает идемпотентность
- Режим проверки: пробный запуск с --check