← Ansible
16 мин · средне · Урок 10 из 12

Динамический inventory и коллекции

Статический inventory не масштабируется в облаке. Inventory-плагины (AWS, Yandex Cloud), группировка по тегам, и коллекции из Galaxy.

Проблема статического inventory в облаке

В облаке хосты появляются и исчезают постоянно. Автоскейлинг поднял ещё три инстанса, а в inventory.ini их нет. Старый инстанс удалили, но его IP всё ещё лежит в файле. При пересоздании инстансы получают новые IP.

Поддерживать inventory.ini вручную в таких условиях невозможно: он устаревает быстрее, чем успеваешь его редактировать.

Нужен inventory, который в момент запуска плейбука генерируется из источника правды: из API облака.

Статический vs динамический inventory

Статический inventory — файл, который ты редактируешь руками. Ansible просто читает список хостов из inventory.ini или inventory.yml. Хорошо работает, когда хостов мало и они не меняются.

При динамическом inventory Ansible спрашивает облако "какие хосты сейчас существуют?" и получает актуальный список в реальном времени. Группировка, IP-адреса, переменные — всё из API, не из файла.

Как это работает сегодня: inventory-плагины

Раньше динамический inventory делали через исполняемые скрипты (*.py), которые при запуске с флагом --list возвращали JSON с хостами. Ansible вызывал скрипт и читал вывод. Это работало, но было неудобно: скрипт надо было передавать через -i script.py, поддерживать зависимости, документировать параметры.

Сегодня стандарт — inventory-плагины. Плагин — декларативный yaml-файл, который описывает, откуда брать хосты и как их группировать. Ansible сам обращается к API через плагин. Скрипты остались как легаси: они ещё встречаются в старых проектах, но для новых всегда используй плагины.

Конфиг inventory-плагина

Конфиг плагина — обычный yaml-файл с особым именем: оно должно заканчиваться на .aws_ec2.yml (или .aws_ec2.yaml) для EC2-плагина. Ansible определяет, какой плагин использовать, по суффиксу файла.

Ansible вызываешь через флаг -i, так же как со статическим inventory, только указываешь yaml-файл плагина или директорию с несколькими файлами:

ansible-playbook -i inventory.aws_ec2.yml site.yml

Пример: AWS EC2

Плагин amazon.aws.aws_ec2 входит в коллекцию amazon.aws.

# inventory.aws_ec2.yml
plugin: amazon.aws.aws_ec2
regions:
  - eu-west-1
  - us-east-1

filters:
  instance-state-name: running
  "tag:Environment": production

keyed_groups:
  - key: tags.Role
    prefix: tag_role
  - key: tags.Environment
    prefix: tag_env

compose:
  ansible_host: public_ip_address

Что здесь происходит:

Если у инстанса тег Role=web, Ansible автоматически создаст группу tag_role_web. В плейбуке можно писать hosts: tag_role_web, и попадёшь на все веб-серверы, сколько бы их ни было.

Для аутентификации в AWS плагин читает стандартные AWS credentials: из переменных окружения AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY, из ~/.aws/credentials или из IAM Instance Profile.

Группировка по тегам: главная польза

keyed_groups — это то, ради чего и нужен динамический inventory в облаке.

Ты тегируешь инстансы при создании (Terraform, CloudFormation, вручную) - например Role=web, Role=db, Environment=staging. Ansible автоматически превращает теги в группы: tag_role_web, tag_role_db, tag_env_staging.

В плейбуке пишешь:

- name: Deploy app
  hosts: tag_role_web
  roles:
    - nginx
    - app

Поднялись 10 новых web-серверов, и плейбук автоматически их увидит. Никаких правок inventory не нужно.

compose дополняет это: позволяет вычислить значение переменной из атрибутов инстанса. Например:

compose:
  ansible_host: public_ip_address
  # или для приватной сети:
  # ansible_host: private_ip_address

Это нужно потому, что inventory-имя инстанса (обычно instance ID вида i-0a1b2c3d) не является IP-адресом. Без compose Ansible не знал бы, куда подключаться по SSH.

Yandex Cloud и другие провайдеры

AWS EC2 — не единственный вариант. У большинства облачных провайдеров есть свои inventory-плагины в соответствующих коллекциях.

Для Yandex Cloud плагин поставляется через официальную коллекцию провайдера. Ищи её на Galaxy Hub как yandex или через документацию Yandex Cloud для Ansible. Принцип тот же: yaml-конфиг с параметрами фильтрации и группировки, аутентификация через IAM-токен или сервисный аккаунт.

Аналогично работают плагины для GCP (google.cloud.gcp_compute), Azure (azure.azcollection.azure_rm), DigitalOcean, Hetzner и других. Ищи коллекцию провайдера на galaxy.ansible.com, читай её документацию.

Отладка: что плагин реально разрешил

Два незаменимых инструмента при работе с динамическим inventory:

# Показать весь inventory как JSON - хосты, группы, переменные
ansible-inventory -i inventory.aws_ec2.yml --list

# Показать дерево групп и хостов - удобно для быстрой проверки
ansible-inventory -i inventory.aws_ec2.yml --graph

--graph даст примерно такое:

@all:
  |--@tag_role_web:
  |  |--i-0a1b2c3d
  |  |--i-0e4f5g6h
  |--@tag_role_db:
  |  |--i-0i7j8k9l
  |--@ungrouped:

Если видишь не то, что ожидал, смотри --list, там все переменные хоста включая ansible_host.

Коллекции: откуда берутся плагины и модули

Начиная с Ansible 2.10 большинство модулей и плагинов живут не в ядре Ansible, а в коллекциях. Коллекция — это отдельный пакет с модулями, плагинами (в том числе inventory), ролями и фильтрами, объединёнными под одним пространством имён.

Формат имени: namespace.collection. Примеры:

КоллекцияЧто внутри
amazon.awsEC2, S3, RDS, IAM и inventory-плагин aws_ec2
community.generalсотни модулей для разных систем и сервисов
ansible.posixмодули для POSIX-систем: authorized_key, mount, sysctl
kubernetes.coreмодули для Kubernetes
community.dockerdocker_container, docker_image и другие

Модули теперь называются полным именем, FQCN (Fully-Qualified Collection Name): amazon.aws.ec2_instance, community.general.ufw, ansible.posix.authorized_key. Это позволяет иметь модули с одинаковым коротким именем в разных коллекциях без конфликтов.

В плейбуках можно писать короткие имена (ec2_instance) если коллекция уже в collections: блоке плея, но FQCN — более явный и надёжный вариант.

Установка коллекций через ansible-galaxy

# Установить одну коллекцию
ansible-galaxy collection install amazon.aws

# Установить конкретную версию
ansible-galaxy collection install amazon.aws:==8.0.0

Коллекции устанавливаются в ~/.ansible/collections/ по умолчанию.

Для воспроизводимых окружений фиксируй зависимости в requirements.yml. Этот файл поддерживает и коллекции, и роли в двух разных блоках:

# requirements.yml
collections:
  - name: amazon.aws
    version: ">=8.0.0"
  - name: community.general
    version: ">=9.0.0"
  - name: ansible.posix

roles:
  - name: geerlingguy.nginx
    version: "3.2.0"
  - name: geerlingguy.postgresql
    version: "3.4.3"

Роли и коллекции ставятся разными подкомандами:

ansible-galaxy role install -r requirements.yml        # только блок roles:
ansible-galaxy collection install -r requirements.yml  # только блок collections:

С Ansible 2.10+ есть шорткат ansible-galaxy install -r requirements.yml, который читает из одного файла оба блока сразу. На старых версиях так не выйдет, там команды нужно запускать по отдельности.

Роли vs коллекции: разница

Вопрос, который часто возникает.

Роль — один переиспользуемый юнит: набор задач, хендлеров, шаблонов, переменных для решения одной задачи (например "настроить nginx"). Роль не содержит модулей или плагинов.

Коллекция — это пакет, который может содержать всё сразу: модули, плагины (включая inventory-плагины), фильтры, роли, и документацию к ним. Всё под одним пространством имён. amazon.aws — это коллекция, внутри которой есть и модули (ec2_instance, s3_object), и inventory-плагин (aws_ec2).

Если ты пишешь переиспользуемую автоматизацию, пишешь роль. Если ты разрабатываешь новые модули или хочешь сгруппировать роли + модули под одним именем, пишешь коллекцию.

Диаграмма: как работает динамический inventory

ОБЛАЧНОЕ API AWS / YC / GCP инстансы + теги INVENTORY-ПЛАГИН amazon.aws.aws_ec2 keyed_groups + compose inventory.aws_ec2.yml ГРУППА: tag_role_web web-01 web-02 web-03 hosts: tag_role_web ГРУППА: tag_role_db db-01 db-02 hosts: tag_role_db ansible-inventory --graph показывает результат группировки

Что важно запомнить

В облаке используй динамический inventory через плагины: файл с суффиксом .aws_ec2.yml (или аналог для своего провайдера). Статический inventory.ini устаревает при первом же изменении инфраструктуры.

keyed_groups автоматически создаёт группы из тегов инстансов. compose устанавливает ansible_host из нужного IP-атрибута.

ansible-inventory --list и --graph — первые команды при отладке, если inventory разрешился не так, как ожидалось.

Коллекции (amazon.aws, community.general и другие) — пакеты с модулями и плагинами. Устанавливаются через ansible-galaxy collection install, фиксируются в requirements.yml под ключом collections:.

FQCN (amazon.aws.ec2_instance) — полное имя модуля: namespace + collection

Дальше разберём секреты: Ansible Vault.

Дрилл · вопросы как на собесе

Проверь себя без подсказок

Сформулируй ответ вслух или письменно, потом раскрой и честно отметь: знал или нет.

01

Динамический inventory: cloud-плагины (aws_ec2, gcp_compute), кастомные скрипты — когда что выбирать?

ANS-022
02

Чем module отличается от plugin? Какие типы плагинов есть (callback, lookup, filter)?

ANS-013

Прошли материал до конца? Отметьте урок пройденным.