Ad-hoc команды для быстрых задач
Урок 6 - выполняем разовые задачи без playbook через ad-hoc команды.
«Не всё стоит писать в playbook. Иногда нужно просто перезапустить сервис на всех серверах - прямо сейчас».
Ad-hoc команда - это разовый запуск одного модуля без playbook. Она удобна для быстрых операций: проверить связь, посмотреть аптайм, установить пакет, перезапустить сервис. Формат: ansible <группа> -m <модуль> -a "<аргументы>".
Полезные примеры
# Узнать uptime всех веб-серверов
ansible web -m command -a "uptime"
# Установить пакет (нужны права root, поэтому --become)
ansible web -m ansible.builtin.apt -a "name=htop state=present" --become
# Перезапустить nginx на всех веб-серверах
ansible web -m ansible.builtin.service -a "name=nginx state=restarted" --become
# Собрать все факты об одном хосте
ansible web1.example.com -m setup
Флаг --become повышает права через sudo - он нужен для действий, требующих root (установка пакетов, управление сервисами). Модуль command просто выполняет команду (без shell-возможностей вроде пайпов), setup - собирает факты о хосте.
Как работает под капотом
Ad-hoc команда - это, по сути, playbook из одной задачи, который Ansible собирает на лету. Он раскрывает группу в хосты, для каждого устанавливает SSH-соединение, копирует указанный модуль с аргументами, выполняет, собирает результат. Разница с playbook только в том, что описание задачи ты передал прямо в командной строке, а не в файле.
Смоделируем, как Ansible применяет один модуль к группе хостов и собирает сводку changed/ok.
# Применяем ad-hoc "service restart" к группе и считаем сводку
web_hosts = ["web1", "web2", "web3"]
def restart_service(host, service):
# имитация: сервис всегда переводится в restarted -> это change
return {"host": host, "service": service, "changed": True, "state": "restarted"}
results = [restart_service(h, "nginx") for h in web_hosts]
changed = sum(1 for r in results if r["changed"])
print(f"web : ok={len(results)} changed={changed}")
for r in results:
print(f" {r['host']}: {r['service']} -> {r['state']}")
Попробуй сам ▶ Каждый рестарт - это changed, потому что «перезапустить» - всегда действие. А вот state=started у уже запущенного сервиса вернул бы ok без изменений: разница между «обеспечь запущенность» и «перезапусти» - важная и про идемпотентность.
Частые ошибки
- Забыть --become. Установка пакетов и управление сервисами требуют root. Без повышения прав - «Permission denied».
- Использовать command там, где нужен shell. Модуль
commandне понимает пайпы, перенаправления и переменные окружения - для них естьshell(но злоупотреблять им не стоит). - Делать через ad-hoc то, что повторяется. Если команда нужна регулярно - её место в playbook под git, а не в истории терминала.
Best practices
- Ad-hoc - для разовых операций и диагностики. Повторяемое - в playbook.
- Предпочитай специализированные модули (
service,apt) сыромуcommand- они идемпотентны. - Модуль
setup- твой друг при отладке: показывает все факты, которые можно использовать в шаблонах.
В реальной работе
Ad-hoc команды незаменимы в инцидентах. Упал сервис на десяти серверах в три часа ночи - одной командой ansible web -m service -a "name=nginx state=restarted" --become ты поднимаешь его везде сразу, не заходя на каждую машину руками. Так же быстро собирают диагностику: ansible all -m command -a "df -h" покажет свободное место на всех дисках парка. Но есть железное правило: если ты выполнил ad-hoc команду дважды - значит, она повторяется, и её место в playbook под git. Ad-hoc - это скальпель для разовых операций и расследований, а не замена воспроизводимой автоматизации.
Итоги
Ad-hoc команды позволяют быстро выполнить один модуль на группе хостов без playbook - идеально для диагностики и разовых действий. Для root-операций нужен --become. Повторяющееся лучше оформить в playbook, к которому мы переходим дальше.