Из чего состоит ad hoc команда
Базовый синтаксис один на все случаи:
Код: Выделить всё
ansible <pattern> -m <module> -a '<args>'
Самый первый ad hoc ansible запускает почти каждый, кто настроил инвентарь, - проверка связи:
Код: Выделить всё
ansible all -m ansible.builtin.ping
Полезные флаги, которые встречаются в ansible команды постоянно:
- -b (--become) - выполнить с повышением привилегий, по сути sudo. Нужно почти для всего, что меняет систему.
- -K (--ask-become-pass) - спросить пароль sudo интерактивно.
- -u user - под каким пользователем подключаться по SSH.
- -f N (--forks) - сколько хостов обрабатывать параллельно. По умолчанию 5. На большом парке -f 30 заметно ускоряет диагностику.
- -i hosts - явный путь к инвентарю.

command против shell: главная развилка
Это место, где новички спотыкаются чаще всего, поэтому разберём подробно. Есть два модуля для запуска произвольных команд, и они не взаимозаменяемы.
ansible.builtin.command запускает программу напрямую, минуя оболочку. Никакого bash между Ansible и бинарником нет. Значит, не работают перенаправления (>, >>), конвейеры (|), подстановки переменных ($HOME), джокеры (*) и операторы && / ||. Это не баг, а защита: меньше неожиданностей и меньше дыр для инъекций. Поэтому command - модуль по умолчанию и предпочтительный выбор:
Код: Выделить всё
ansible web -m ansible.builtin.command -a 'uptime'
ansible web -a 'systemctl is-active nginx'
ansible.builtin.shell прогоняет команду через /bin/sh на удалённом узле. Здесь уже доступны и пайпы, и перенаправления, и переменные окружения. Берёшь shell тогда и только тогда, когда тебе реально нужна оболочка:
Код: Выделить всё
ansible web -m ansible.builtin.shell -a 'cat /var/log/messages | grep -i error | tail -20'
И ещё важное: оба модуля не идемпотентны. Они выполняются каждый прогон и всегда рапортуют changed. Ansible не знает, что делает твоя команда, поэтому не умеет проверить "а надо ли". Прежде чем тянуться к command/shell, спроси себя: нет ли профильного модуля? Для пакетов есть dnf, для сервисов service, для файлов file и copy. Профильный модуль идемпотентен и сам понимает, менять что-то или нет.
Реальные ad hoc команды на каждый день
Соберём набор, который реально выручает. Это и есть живые ansible примеры, а не учебные заглушки.
Скопировать файл на группу хостов:
Код: Выделить всё
ansible web -b -m ansible.builtin.copy \
-a 'src=/etc/motd dest=/etc/motd owner=root group=root mode=0644'
Код: Выделить всё
ansible web -b -m ansible.builtin.file \
-a 'path=/opt/app state=directory owner=deploy mode=0755'
Код: Выделить всё
ansible all -b -m ansible.builtin.user \
-a 'name=deploy state=present groups=wheel append=yes'
Код: Выделить всё
ansible web -b -m ansible.builtin.service \
-a 'name=httpd state=restarted enabled=yes'
Код: Выделить всё
ansible db -b -m ansible.builtin.dnf -a 'name=postgresql-server state=present'
Код: Выделить всё
ansible web -b -m ansible.posix.firewalld \
-a 'service=http permanent=yes immediate=yes state=enabled'
Код: Выделить всё
ansible web -b -m ansible.builtin.reboot -a 'reboot_timeout=600'
Код: Выделить всё
ansible web -m ansible.builtin.setup -a 'filter=ansible_distribution*'
Типичные грабли
- Забыл -b. Команда отрабатывает, но "Permission denied" сыплется на каждой второй задаче. Всё, что трогает систему, требует sudo - добавляй -b (и -K, если sudo с паролем).
- Спецсимволы в command. Написал ansible -a 'echo $HOME > /tmp/x' и удивляешься, почему файл пуст, а в значении буквально строка "$HOME". Редиректы и переменные - это shell, не command.
- Кавычки и шелл хоста vs локальный шелл. Внешние одинарные кавычки -a '...' защищают строку от твоего локального bash. Путаница с вложенными кавычками - классический источник ошибок парсинга.
- Ждёшь идемпотентности от command/shell. Они всегда changed. Если нужно "сделать только если надо" - бери профильный модуль или добавляй creates= / removes= у самого command.
- Маленький -f на большом парке. По умолчанию пять хостов за раз. На сотне узлов диагностика тянется минутами без нужды - подними forks.
Правило простое. Ad hoc - для разового и для диагностики: проверить связь, посмотреть факты, перезапустить сервис, разово дозалить файл, потушить пожар. Как только действие нужно повторять, оно состоит из нескольких шагов, его надо хранить в git и ревьюить - это плейбук. Одна команда сегодня превращается в "а помнишь, что мы там запускали" через месяц; плейбук - это документация, которая ещё и исполняется.
Про экзамен EX294. На RHCE ad hoc команды почти не спрашивают как самостоятельное задание - там оценивают плейбуки и роли. Но ad hoc - твой главный инструмент проверки во время самого экзамена: накатил роль - тут же ad hoc-ом сходи и убедись, что сервис поднялся, порт открыт, пакет стоит. Это экономит время и нервы. Так что знать их надо твёрдо, просто не ради отдельного билета.
Мини-лаба
Подними пару тестовых узлов (виртуалки RHEL/Rocky/Fedora) и пропиши их в инвентарь группой web. Затем руками прогони:
- ansible web -m ansible.builtin.ping - убедись, что канал есть.
- ansible web -m ansible.builtin.setup -a 'filter=ansible_distribution*' - посмотри дистрибутив.
- Поставь httpd через dnf, запусти и включи через service, открой http в firewalld - тремя ad hoc командами с -b.
- Повтори те же три команды второй раз и посмотри на changed/ok: профильные модули на втором прогоне покажут ok, а command/shell - всегда changed.
- Сделай ansible web -m ansible.builtin.command -a 'echo $HOME' и ansible web -m ansible.builtin.shell -a 'echo $HOME' - сравни вывод и пойми разницу на практике.
- Чем ansible.builtin.command отличается от ansible.builtin.shell и в каком случае нужен именно shell?
- Почему модули command и shell всегда показывают changed, а dnf или service - не всегда?
- Что делают флаги -b, -K и -f, и зачем поднимать forks на большом парке?
- Где проходит граница: какие задачи логично делать через ad hoc, а какие пора оформлять плейбуком?
Ad hoc команды - это скальпель для разовых дел и диагностики: ansible <pattern> -m <module> -a '<args>', и задача выполнена на всём парке сразу. Помни главное: command по умолчанию и безопаснее, shell - только под пайпы и редиректы, оба не идемпотентны, а для системных изменений почти всегда есть профильный модуль получше. Освоишь ad hoc - и проверка инфраструктуры станет вопросом одной строки в терминале, а на экзамене EX294 у тебя будет под рукой быстрый способ убедиться, что роль и правда сработала.