Зависимости ролей и requirements.yml

Рейтинг: 70.1% · 9 голосов
Подробный курс по Ansible с прицелом на экзамен RHCE EX294: установка и инвентарь, плейбуки, переменные и факты, Vault, циклы и условия, шаблоны Jinja2, роли и коллекции, Execution Environments и ansible-navigator, управление системами (диски, LVM, cron, SELinux, firewalld). Примеры на RHEL/Fedora. Актуально на 2026.
Ответить
Аватара пользователя
Maksim_DevOps
Сообщения: 47
Зарегистрирован: 11 май 2026, 05:31

Зависимости ролей и requirements.yml

Сообщение Maksim_DevOps »

Оглавление курса (47)
  1. Что такое Ansible и зачем он нужен: автоматизация без агентов
  2. Сертификация RHCE и экзамен EX294: что внутри и как готовиться
  3. Архитектура Ansible: control node, узлы, модули и плагины
  4. Установка Ansible на control node: dnf, pip и версии ansible-core
  5. Подготовка управляемых узлов: SSH, пользователь и sudo
  6. Инвентарь Ansible: hosts, группы и переменные
  7. Настройка Ansible: файл ansible.cfg и приоритеты конфигурации
  8. Host patterns и инструменты командной строки Ansible
  9. Ad hoc команды Ansible: быстрые задачи без плейбука
  10. Ansible playbook: что это такое и как устроен
  11. Структура плейбука: play, task, модули и переменные
  12. Запуск плейбуков: проверка, теги, ограничения и отладка
  13. Параллелизм и порядок выполнения: forks, serial, strategy
  14. Факты Ansible: сбор информации об узлах
  15. Переменные Ansible: типы, объявление и приоритет
  16. Регистрация результатов и специальные переменные
  17. Ansible Vault: шифрование паролей и секретов
  18. Организация инвентаря: group_vars, host_vars и вложенные группы
  19. Динамический инвентарь и инвентарные плагины
  20. Циклы в Ansible: loop, списки и словари
  21. Повтор задачи до условия: until, retries и delay
  22. Условия в Ansible: директива when и логика
  23. Jinja2 в Ansible: выражения, фильтры и подстановки
  24. Обработчики Ansible: handlers, notify и flush_handlers
  25. Обработка ошибок: failed_when, changed_when и ignore_errors
  26. Блоки в Ansible: block, rescue и always
  27. Управление файлами: модули file, copy, fetch и stat
  28. Архивы и сборка файлов: archive, unarchive, assemble
  29. Точечное редактирование файлов: lineinfile и blockinfile
  30. Шаблоны Jinja2: модуль template и динамические конфиги
  31. Jinja2 продвинуто: фильтры, циклы, макросы и lookup
  32. Модули Ansible: ansible-doc и поиск нужного модуля
  33. Разработка собственного модуля Ansible на Python
  34. Роли Ansible и Ansible Galaxy: переиспользование
  35. Разработка роли Ansible: создание с нуля
  36. Зависимости ролей и requirements.yml (вы здесь)
  37. Коллекции Ansible: ansible.posix, community и своя коллекция
  38. Execution Environments: контейнеры для запуска Ansible
  39. Сборка Execution Environment с ansible-builder
  40. ansible-navigator: запуск плейбуков в Execution Environment
  41. Управление SSH-ключами через Ansible: authorized_key
  42. Управление дисками: filesystem, mount и parted
  43. LVM через Ansible: тома, группы и расширение
  44. Планировщик задач: cron и systemd timers через Ansible
  45. Безопасность: hardening SSH и репозитории dnf/yum
  46. SELinux через Ansible: булевы, контексты и порты
  47. Сквозной проект и подготовка к экзамену EX294
Ты собрал пару своих ролей, и всё вроде работает. Но в реальном проекте роли никогда не живут поодиночке. Роль для приложения хочет, чтобы заранее был настроен веб-сервер. Чужая роль из Galaxy тянет за собой ещё три. Коллега клонирует репозиторий, запускает плейбук - и получает "role not found", потому что половина ролей лежит вообще в другом месте. Решается это двумя механизмами: внутренними зависимостями ролей через meta/main.yml и внешним манифестом requirements.yml, по которому ansible-galaxy подтянет всё нужное одной командой. Разберём оба, потому что зависимости ролей ansible - это то, на чём люди регулярно спотыкаются и в бою, и на экзамене.

Зависимости ролей: dependencies в meta/main.yml

Внутри каждой роли есть файл meta/main.yml. Помимо метаданных автора и лицензии там живёт ключ dependencies - список ролей, которые должны отработать ДО запуска текущей. Это и есть ansible role dependencies в чистом виде.

Допустим, у тебя есть роль myapp, и она бессмысленна без nginx. Описываем зависимость:

Код: Выделить всё

# roles/myapp/meta/main.yml
---
galaxy_info:
  author: cyberlake
  description: Деплой нашего приложения
  license: MIT
  min_ansible_version: "2.14"
  platforms:
    - name: EL
      versions:
        - "9"

dependencies:
  - role: nginx
  - role: postgresql
    vars:
      pg_version: 16
Теперь, когда в плейбуке ты подключаешь только myapp, Ansible сам прогонит сначала nginx, потом postgresql, и лишь затем задачи самой myapp. Параметры зависимой роли можно прокинуть прямо тут через vars - удобно, когда одна и та же роль настраивается под конкретного потребителя.

Код: Выделить всё

# site.yml
---
- name: Развернуть приложение
  hosts: app_servers
  become: true
  roles:
    - role: myapp
Важная тонкость про порядок: зависимости выполняются ДО основной роли и в том порядке, в каком перечислены. Если nginx и postgresql сами зависят друг от друга или от третьей роли - Ansible построит дерево и не запустит одну и ту же роль дважды.

Изображение

allow_duplicates: когда роль нужна несколько раз

По умолчанию роль, уже отработавшая как чья-то зависимость, повторно в том же play не запускается. Это спасает от бесконтрольного дублирования: если десять ролей зависят от common, common прогонится один раз. Логика идемпотентности: один и тот же набор задач не должен молотиться вхолостую.

Но иногда повтор нужен по делу. Классика - роль, которая создаёт виртуальный хост или раскатывает один инстанс сервиса, и ты хочешь вызвать её несколько раз с разными параметрами. Тогда в meta/main.yml самой переиспользуемой роли ставим:

Код: Выделить всё

# roles/vhost/meta/main.yml
---
allow_duplicates: true

dependencies: []
С таким флагом каждый вызов vhost (например, из dependencies другой роли или просто в списке roles) отработает заново, даже если параметры совпадают. Без флага второй и последующие вызовы Ansible тихо пропустит - и ты будешь долго гадать, почему создался только первый виртуальный хост.

requirements.yml: внешние роли и коллекции

Зависимости в meta/main.yml хороши, но они описывают связи МЕЖДУ ролями. А откуда взять сами роли и коллекции, если их нет в репозитории? Здесь на сцену выходит ansible requirements.yml - манифест внешних зависимостей проекта. Это не часть Ansible-движка, это вход для утилиты ansible-galaxy. Файл обычно кладут в корень проекта или в каталог collections/.

Формат у файла два раздела: roles и collections. Минимальный пример:

Код: Выделить всё

# requirements.yml
---
roles:
  - name: geerlingguy.nginx
    version: "3.1.4"

  - name: internal-app
    src: https://git.cyberlake.ru/devops/role-internal-app.git
    scm: git
    version: v2.0.1

collections:
  - name: community.general
    version: ">=8.0.0"

  - name: ansible.posix
    version: "1.5.4"
Что тут происходит по строкам:
  • name + version для роли из Galaxy - тянется по имени namespace.role с указанной версией. Это и есть базовый ansible galaxy requirements.
  • src + scm: git + version - роль берётся напрямую из git-репозитория. version здесь это тег, ветка или коммит. На проде всегда пинуй тег или хеш коммита, а не ветку main, иначе сборка перестанет быть воспроизводимой.
  • collections - современные модули типа ansible.posix.firewalld и community.general.parted живут именно в коллекциях, поэтому без этого раздела ты далеко не уедешь. version поддерживает диапазоны (>=, <, ==).
Версионирование - не формальность. Завтра в geerlingguy.nginx 4.0.0 поменяется поведение, и без пина version твой плейбук однажды утром просто сломается. Пинуй версии, как пинуешь зависимости в любом нормальном проекте.

Установка: ansible-galaxy install -r requirements.yml

Дальше всё ставится одной командой. Современный ansible-core понимает оба раздела сразу:

Код: Выделить всё

ansible-galaxy install -r requirements.yml
Если хочешь управлять путями раздельно (а на практике так чище), ставь роли и коллекции отдельными подкомандами:

Код: Выделить всё

# Роли - в каталог roles/
ansible-galaxy role install -r requirements.yml -p roles/

# Коллекции - в каталог collections/
ansible-galaxy collection install -r requirements.yml -p collections/
Полезные флаги: --force переустановит то, что уже стоит (нужно, когда обновил version в манифесте), -p задаёт путь установки. Куда Ansible потом ищет роли и коллекции, определяется в ansible.cfg:

Код: Выделить всё

# ansible.cfg
[defaults]
roles_path = ./roles:/etc/ansible/roles
collections_path = ./collections
Сам ansible-galaxy в системе RHEL/Fedora приезжает вместе с пакетом ansible-core (dnf install ansible-core), отдельно ставить ничего не надо. В Debian/Ubuntu это apt install ansible, в RED OS и Astra - штатный ansible-core из репозитория дистрибутива, команды один в один.

Связь с экзаменом. На RHCE (EX294, версия под RHEL 9) умение взять готовый requirements.yml и развернуть по нему роли и коллекции - реальный практический навык. Тебе вполне могут дать заранее подготовленный файл и попросить установить из него роль, а потом применить её к группе хостов. Знать, что collections тоже описываются в этом файле и что install -r ставит и то и другое - ровно тот минимум, на котором не стоит срезаться.

Типичные грабли
  • Забыл коллекцию в requirements.yml. Плейбук падает на "couldn't resolve module ansible.posix.firewalld". Модуль живёт в коллекции ansible.posix - значит, коллекция должна быть в манифесте и установлена.
  • Пин на ветку вместо тега. version: main для git-роли = лотерея при каждой установке. Тег или хеш коммита.
  • Дубликат роли не отрабатывает. Вызвал роль второй раз, а она молчит - не забыл ли allow_duplicates: true.
  • roles_path не настроен. Поставил роли через -p roles/, а Ansible ищет в /etc/ansible/roles. Пропиши roles_path в ansible.cfg рядом с проектом.
  • meta/main.yml невалиден. Если в зависимостях опечатка или роль не найдена - play не стартует вовсе, ошибка вылезает на этапе разбора зависимостей, до первой задачи.
Шеринг роли и финальные заметки

Когда роль вылизана и идемпотентна, её не грех опубликовать. Через свой аккаунт Galaxy импортируешь git-репозиторий роли, и она становится доступна как namespace.role в чужих requirements.yml. Правила хорошего тона: осмысленный meta/main.yml с лицензией и platforms, README с переменными, семантические теги версий в git.

И две мысли про роли в целом. Первое - дроби роль, когда у неё появляется второй смысл. Роль должна делать одну понятную вещь (поставить и настроить nginx), а не "развернуть весь стек". Второе - роль обязана быть идемпотентной целиком: повторный запуск на настроенной машине не меняет ничего и весь вывод зелёный (ok), а не жёлтый (changed). Если при втором прогоне роль что-то "чинит" каждый раз - значит, где-то command вместо нормального модуля или забытый creates/changed_when.

Мини-лаба
  • Создай роль myapp, в её meta/main.yml пропиши dependencies на роль common. Убедись, что common отрабатывает первой.
  • Напиши requirements.yml с одной ролью из Galaxy (с пином version) и двумя коллекциями (community.general, ansible.posix).
  • Установи всё: ansible-galaxy install -r requirements.yml. Затем разнеси установку на role install и collection install с -p.
  • Возьми переиспользуемую роль, поставь allow_duplicates: true и вызови её дважды с разными vars - проверь, что отработали оба вызова.
  • Прогони итоговый плейбук дважды подряд и убедись, что второй прогон полностью идемпотентен (changed=0).
Контрольные вопросы
  • В каком файле роли описываются её внутренние зависимости и в каком порядке они выполняются относительно основной роли?
  • Чем отличается раздел roles от collections в requirements.yml и почему коллекции вообще нужны?
  • Что делает allow_duplicates: true и в какой ситуации без него роль не отработает повторно?
  • Какой командой установить разом роли и коллекции из манифеста и как разнести их по разным каталогам?
Итог

Зависимости ролей через meta/main.yml связывают роли между собой и задают порядок их выполнения, allow_duplicates разрешает осознанный повтор. requirements.yml - это манифест внешних зависимостей для ansible-galaxy: roles тянут роли из Galaxy и git, collections подтягивают современные модули. Команда ansible-galaxy install -r requirements.yml ставит всё одним движением и делает проект воспроизводимым на любой машине. Пинуй версии, держи роли маленькими и идемпотентными - и сборка не развалится ни у коллеги, ни на экзамене.
👍 ❤️4 🔥1 😄 🤔
Аватара пользователя
terranno
Сообщения: 1
Зарегистрирован: 17 май 2026, 02:15

Re: Зависимости ролей и requirements.yml

Сообщение terranno »

Долго не мог понять, почему роль из dependencies второй раз не запускается - оказалось ровно про allow_duplicates, спасибо. Теперь vhost-ы создаются все, а не только первый.
👍1 ❤️1 🔥 😄 🤔2
Аватара пользователя
torchnerd
Сообщения: 1
Зарегистрирован: 13 май 2026, 08:58

Re: Зависимости ролей и requirements.yml

Сообщение torchnerd »

Вопрос: а если в requirements.yml роль из git без version указать, что подтянется - последний коммит main? На проде же так нельзя?
👍2 ❤️ 🔥 😄 🤔2
Ответить
← Предыдущая глава
Разработка роли Ansible: создание с нуля
Следующая глава →
Коллекции Ansible: ansible.posix, community и своя коллекция

Все главы курса «Ansible: автоматизация и подготовка к RHCE (EX294)»

Поделиться темой: ✈ Telegram VK
Похожие запросы: как создать роль ansible с нуля и структура каталогов

Вернуться в «Ansible: автоматизация и подготовка к RHCE (EX294)»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость