Аннотация. В этой части продолжаем разбирать инвентарь Ansible простыми словами: порядок загрузки, переменные (групповые и хостовые), псевдонимы, поведенческие параметры подключения и подводные камни. С готовыми INI/YAML примерами и чек‑листом.
Управление порядком загрузки инвентаря
Что это. Ansible может собирать инвентарь из нескольких источников: файла INI/YAML, целой директории, нескольких -i подряд, динамического инвентаря. Все эти источники объединяются в один «каталог» хостов и групп.
Как управлять.
- Указывайте один базовый путь в ansible.cfg — так меньше сюрпризов:
[defaults]
inventory = inventories/dev
- Если всё же нужно несколько источников: ansible -i inventories/dev -i inventories/common .... Ansible объединит группы и хосты.
- Детерминированность важна. Чтобы гарантировать предсказуемый порядок применения групповых переменных, стройте иерархию через :children (дочерние группы), а не надейтесь на «магический» порядок объединения несвязанных групп.
Подводные камни.
- Один и тот же хост в разных несвязанных группах с одинаковыми ключами → «кто победит» неочевидно. Решение: вынесите конфликтующие ключи в host_vars/<hostname>.yml.
- Смешивание форматов в одной директории (INI+YAML) допустимо, но проще придерживаться одного стиля на проект.
Переменные в инвентаре: зачем и как
Зачем. Переменные позволяют описать окружение: версии, порты, пути, учетные записи, параметры подключения. Благодаря этому роли становятся переиспользуемыми.
Где хранить.
- В инвентаре (в файле INI/YAML): быстро и локально для примеров/демо.
- В group_vars/ и host_vars/: масштабируется, удобно для большого проекта.
- В vars_files роли/плейбука: когда переменные — часть роли.
Правило простоты. Общие значения — в группах, исключения — в host_vars. Чем ниже по иерархии, тем «ближе к железу».
Переменные хоста (host vars): INI и YAML на примере
Пример INI:
Здесь app-1 и app-2 задают хостовые переменные прямо в строке. app-3 унаследует http_port=8080 из группы.
То же самое на YAML:
Важно. Хостовые переменные всегда «сильнее» групповых.
Псевдонимы инвентаря (inventory aliases)
Зачем. Удобно называть хост по‑человечески (alias), а реальный адрес хранить отдельно — меняется IP, а имя в инвентаре остаётся.
INI:
[web]
web1 ansible_host=10.10.0.5 ansible_user=ubuntu \
ansible_ssh_private_key_file=~/.ssh/web1.pem
inventory_hostname = web1, подключение идёт к ansible_host.
YAML:
Подсказка. Старайтесь использовать alias без домена (web1), а FQDN хранить в ansible_host — так легче мигрировать DNS/IP.
Определение переменных в INI
Варианты:
Подводные камни.
- Пробелы вокруг = не критичны, но лучше писать key=value.
- Булевы значения пишите как строки ("true"/"false") или явно проверяйте в шаблонах.
- Не используйте зарезервированные имена для собственных значений (например, inventory_hostname).
Наследование значений (группы групп)
Ключевая идея. Группа может быть «родителем» другой группы через :children (INI) или вложенность (YAML). Значения переменных из дочерней группы переопределяют такие же ключи из родительской. Если хост входит в несвязанные (не родственные) группы с одинаковым ключом — порядок не гарантирован, рассчитывать на «кто победит» нельзя.
Как задать родителя и ребёнка
INI:
YAML:
Правила приоритета (только в инвентаре)
- host_vars ▶ переменные дочерней группы ▶ переменные родительской группы ▶ all:vars.
- Несвязанные группы (нет родства через :children) — приоритет не определён. Не кладите один и тот же ключ в такие группы.
- Inline‑переменные в строке хоста в INI трактуются как хостовые (т.е. выше групповых).
- group_vars/<group>.yml и блок [group:vars] — это один уровень приоритета (выбирайте один стиль для проекта).
Живой пример и «кто победил»
Задача: задать log_level на разных слоях и понять итог для каждого хоста.
INI:
Разбор:
- app-1.dev.example входит в цепочку env_dev → role_app → app_dev_example. Итог log_level=debug (дочерняя role_app перебила env_dev).
- app-2.dev.example имеет хостовое trace — оно сильнее любых групп.
- Хосты группы role_kafka получат info (их дочерняя role_kafka перебивает env_dev).
Проверка себя:
ansible-inventory -i inventories/dev --graph
ansible -i inventories/dev app_dev_example -m debug -a 'var=log_level'
Организация host_vars и group_vars host_vars и group_vars
Когда использовать.
- Если переменных уже десятки/сотни, уходите из inline‑строк в файлы.
- Секреты — только через Ansible Vault в group_vars/ или host_vars/.
Пример:
Как объединяются переменные и где острые углы
Коротко о приоритетах (только инвентарь):
host_vars ▶ переменные дочерней группы ▶ переменные родительской группы ▶ all:vars.
Списки и словари. По умолчанию Ansible не делает «умные» слияния — последний встретившийся ключ побеждает целиком. Если нужно «склеивать» словари/списки, делайте это явным set_fact с фильтром combine/unique или в шаблоне Jinja2.
Параметры подключения (поведенческий инвентарь)
Это «как именно стучаться к хосту». Эти ключи не про бизнес‑логику ролей, а про транспорт: через что подключаться, под каким пользователем, куда класть временные файлы, как поднимать привилегии.
Мини‑словарик ключей
- ansible_connection — способ подключения: ssh (по умолчанию), local, docker, kubectl, winrm (Windows), chroot и др.
- ansible_host — реальный адрес/имя узла (IP/FQDN). В инвентаре можно оставить короткий alias, а сюда положить адрес.
- ansible_port — порт транспорта (обычно 22 для SSH, 5985/5986 для WinRM).
- ansible_user / ansible_password — учётка удалённой машины. Пароли храните в Vault.
- ansible_ssh_private_key_file — путь к приватному ключу для SSH.
- Повышение привилегий: become: true, ansible_become_user (обычно root), ansible_become_method (sudo), ansible_become_password (Vault).
- Исполнители: ansible_python_interpreter (например, /usr/bin/python3), ansible_shell_type (sh, bash), ansible_shell_executable (путь к шеллу).
- Доп. SSH‑аргументы: ansible_ssh_common_args (общие) и ansible_ssh_extra_args (для командной сессии). Полезно для ProxyJump/проксей.
Важно. Переменные окружения удалённого хоста задавайте не в инвентаре, а в плейбуке/роли через environment: — так чище и контролируемее.
Базовые примеры
Linux по SSH с ключом (INI):
То же на YAML:
Частые ошибки новичков и как их избежать
Ниже — «грабли», на которые чаще всего наступают. И быстрые обходные дорожки.
Ошибка 1. Смешали alias и реальный адрес.
- Симптом: меняете IP, а плейбук всё ещё лезет по старому.
- Причина: в инвентаре как inventory_hostname стоит FQDN, а ansible_host не используется.
- Как правильно: alias краткий (web1), реальный адрес в ansible_host.
Ошибка 2. Конфликтующие значения в несвязанных группах.
- Симптом: log_level то info, то debug без логики.
- Причина: один хост состоит в двух группах, не связанных через :children.
- Решение: стройте иерархию (:children), конфликтующие ключи — в host_vars.
Ошибка 3. Пароли в INI.
- Симптом: «секреты» попадают в git.
- Решение: храните в Vault (ansible-vault encrypt), подключайте как обычные vars.
Ошибка 4. Неэкранированные пробелы/спецсимволы.
- Симптом: Ansible «кусает» половину строки.
- Решение: кавычки вокруг значений с пробелами/двоеточиями, особенно в SSH‑аргументах.
Ошибка 5. Нет Python на удалёнке / не тот интерпретатор.
- Симптом: модули падают, ping не работает.
- Решение: поставьте python3, укажите ansible_python_interpreter=/usr/bin/python3.
Ошибка 6. become не работает.
- Симптом: задачи «Permission denied».
- Решение: become: true, правильный ansible_become_user, проверка sudoers. Для некоторых окружений добавьте become_flags=-H -S.
Ошибка 7. Дубли имен хостов.
- Симптом: в --graph один и тот же хост всплывает в разных местах с разными переменными.
- Решение: уникальные inventory_hostname, адрес — через ansible_host.
Ошибка 8. Попытка «склеить» словари/списки «по магии».
- Симптом: часть ключей «пропала» после переопределения.
- Решение: используйте combine/unique явно, не рассчитывайте на hash_behaviour=merge.
Мини‑чеклист самопроверки
ansible-inventory -i inventories/dev --graph # иерархия групп
ansible-inventory -i inventories/dev --list | jq . # что Ansible реально видит
ansible all -m ping -i inventories/dev # подключение
ansible web1 -m debug -a 'var=hostvars[inventory_hostname]' -i inventories/dev | head -n 50
Итог. Держите поведенческие ключи подключения простыми и явными, секреты — в Vault, и всегда проверяйте структуру инвентаря прежде чем грешить на роли/плейбуки.
Почему это работает
Ansible перед выполнением задач собирает переменные со всех источников (инвентарь, group_vars/host_vars, факты, плей), выстраивает их по приоритетам и применяет «самое близкое» значение к хосту. Поэтому: чем ниже по иерархии и ближе к хосту вы задаёте значение, тем выше шанс, что оно переопределит общее.
Что сделали
- Разобрали, как Ansible объединяет инвентарь и почему лучше строить иерархию через :children.
- Показали, где хранить переменные и как аккуратно переопределять их на уровне хоста.
- Разобрали псевдонимы, поведенческие ключи подключения и частые грабли.
Сделать прямо сейчас
- В ansible.cfg укажите единый путь к инвентарю.
- Перенесите общие параметры в group_vars/, а исключения — в host_vars/.
- Наведите порядок: alias в inventory_hostname, адрес в ansible_host.
- Добавьте минимум один плей, который использует эти переменные в действии (шаблон, роль).
CTA
Если было полезно — подпишитесь на серию про Ansible. В комментариях напишите свою схему групп: помогу разложить по group_vars/host_vars и подсвечу риски. В следующей части — динамический инвентарь и constructed‑группы.