Сборка Execution Environment с ansible-builder

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

Сборка Execution Environment с ansible-builder

Сообщение 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
Знакомая боль: плейбук, который вчера крутился у тебя на ноуте, сегодня падает на сервере коллеги. У него другой ansible-core, нет community.general нужной версии, питоновский pywinrm не той ветки, а на CI вообще голый образ. Каждый раз пляска с virtualenv, pip install и "а у меня работает". Execution Environment (EE) закрывает эту дыру: ты упаковываешь ansible-core, коллекции из Galaxy, питон-зависимости и системные пакеты в один OCI-образ. Этот образ одинаково запускается локально через ansible-navigator, в пайплайне и в Automation Platform. А собирает такой образ инструмент ansible builder.

В этом уроке разберём, как ansible-builder превращает декларативный файл execution-environment.yml в Containerfile, как описать зависимости тремя слоями (galaxy, python, system) и как выполнить execution environment build так, чтобы образ был воспроизводимым. В конце соберём рабочий EE с ansible.posix и community.general своими руками.

Что такое Execution Environment и зачем тут ansible-builder

EE - это контейнерный образ, внутри которого лежит всё, что нужно для запуска плейбука: интерпретатор Ansible (ansible-core), ansible-runner как точка входа, набор коллекций и зависимости. По сути это замена старого подхода с "поставь ansible на control node руками". Современный RHCE (EX294 на RHEL 9, AAP 2.2) уже строится вокруг ansible-navigator, который по умолчанию гоняет плейбуки именно в таких EE-образах. На RHEL 10 и AAP 2.5 идея та же.

Сам ansible-builder образы не запускает - он их собирает. Под капотом он читает твой YAML-файл определения, генерирует из него Containerfile (это тот же Dockerfile, только имя файла другое) и отдаёт его в podman (по умолчанию) или docker. То есть сборка ee ansible - это всегда два шага: сгенерировать рецепт и собрать образ. Команда build делает оба за раз.

Ставится инструмент через pip, отдельно от самого Ansible:

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

python3 -m pip install ansible-builder
ansible-builder --version
На RHEL/Fedora питон и pip берутся из dnf (dnf install -y python3-pip), дальше pip ставит сам builder. На Ubuntu/Debian путь аналогичный через apt install python3-pip. В RU-дистрибутивах (RED OS, Astra) ситуация такая же: главное - наличие python3-pip и установленного podman, потому что без контейнерного движка собирать будет нечем.

Изображение

Файл определения execution-environment.yml (version 3)

Сердце сборки - файл execution-environment.yml. Актуальная схема - version 3 (её понимает ansible-builder 3.x). Минимальный, но осмысленный пример:

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

version: 3

images:
  base_image:
    name: registry.redhat.io/ansible-automation-platform/ee-minimal-rhel9:latest

dependencies:
  ansible_core:
    package_pip: ansible-core==2.16.4
  ansible_runner:
    package_pip: ansible-runner
  galaxy: requirements.yml
  python: requirements.txt
  system: bindep.txt

options:
  package_manager_path: /usr/bin/microdnf
Разберём ключи.

base_image - от какого образа отталкиваемся. Для AAP это ee-minimal-rhel9 (минимальный, только ansible-core) или ee-supported-rhel9 (с набором сертифицированных коллекций) из registry.redhat.io - доступ к нему требует логина в Red Hat. Если подписки нет, для учёбы можно взять публичный quay.io/centos/centos:stream9 или образ из community, но тогда ansible-core придётся ставить через тот самый ключ ansible_core.

dependencies - три слоя зависимостей, и это самое важное:
  • galaxy - указывает на requirements.yml в формате ansible-galaxy. Сюда идут коллекции и роли.
  • python - requirements.txt в обычном pip-формате. Сюда питоновские библиотеки, которые нужны модулям (pywinrm, kubernetes, jmespath и т.п.).
  • system - bindep.txt в формате bindep. Это системные RPM-пакеты (компиляторы, dev-заголовки, openssh-clients).
Можно не выносить в отдельные файлы, а писать инлайном списком прямо в dependencies, но для серьёзных проектов отдельные файлы удобнее - их видно в git и переиспользуешь.

additional_build_steps - произвольные команды Containerfile на нужном этапе. Есть несколько точек врезки: prepend_base, append_base, prepend_galaxy, prepend_final, append_final. Например, положить свой ansible.cfg или прогнать дополнительную настройку:

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

additional_build_steps:
  prepend_final:
    - RUN echo "Сборка кастомного EE для прода"
  append_final:
    - RUN ansible-galaxy collection list
Файлы для копирования внутрь образа объявляются в additional_build_files (src/dest), а build_arg_defaults задаёт аргументы сборки по умолчанию.

Практика: сборка ee ansible с ansible.posix и community.general

Собираем рабочий EE. Создаём каталог и четыре файла.

requirements.yml (коллекции из Galaxy):

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

---
collections:
  - name: ansible.posix
    version: ">=1.5.0"
  - name: community.general
    version: ">=8.0.0"
requirements.txt (питон-зависимости, которые тянут модули из этих коллекций):

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

jmespath
passlib
bindep.txt (системные пакеты; синтаксис bindep с тегами платформы и профиля):

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

gcc [platform:rpm compile]
openssh-clients [platform:rpm]
git-core [platform:rpm]
И сам execution-environment.yml:

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

version: 3

images:
  base_image:
    name: registry.redhat.io/ansible-automation-platform/ee-minimal-rhel9:latest

dependencies:
  ansible_core:
    package_pip: ansible-core==2.16.4
  ansible_runner:
    package_pip: ansible-runner
  galaxy: requirements.yml
  python: requirements.txt
  system: bindep.txt

options:
  package_manager_path: /usr/bin/microdnf
Теперь запускаем сборку. Флаг -t задаёт имя и тег образа:

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

ansible-builder build -t myee:1.0 -v 3
Ключ -v 3 повышает детализацию вывода - видно каждый шаг podman. По умолчанию ansible-builder складывает сгенерированный Containerfile и собранные файлы в каталог context. Хочешь сначала только посмотреть рецепт, не собирая образ - есть отдельная команда:

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

ansible-builder create
Она сгенерирует context/Containerfile, но podman не дёрнет. Полезно, когда нужно вручную подправить шаги или прогнать сборку на другом хосте.

Проверяем, что образ собрался и что внутри лежат наши коллекции:

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

podman images | grep myee
podman run --rm myee:1.0 ansible --version
podman run --rm myee:1.0 ansible-galaxy collection list
В выводе последней команды должны быть ansible.posix и community.general нужных версий. Запустить плейбук в этом EE через навигатор:

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

ansible-navigator run site.yml --execution-environment-image myee:1.0 -m stdout
Публикация образа в реестр - обычный podman-флоу, ansible-builder тут ничего особого не делает:

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

podman tag myee:1.0 registry.example.com/automation/myee:1.0
podman login registry.example.com
podman push registry.example.com/automation/myee:1.0
После пуша образ можно подключать в Automation Platform или указывать в ansible-navigator.cfg, чтобы вся команда гоняла плейбуки на одном и том же окружении.

Типичные грабли
  • version: 3 vs version: 1. Старые гайды показывают синтаксис v1 с ключами вроде ansible_config на верхнем уровне. На ansible-builder 3.x он не соберётся. Всегда начинай файл с version: 3.
  • Нет доступа к registry.redhat.io. base_image из ee-minimal требует podman login registry.redhat.io с учёткой Red Hat. Без подписки бери публичный базовый образ и ставь ansible-core через package_pip.
  • EE только для RPM-образов. Слой system через bindep ориентирован на dnf/microdnf. Базовые образы на Debian, Ubuntu или Alpine официально не поддерживаются - не пытайся собрать EE поверх ubuntu:22.04.
  • Забыл питон-зависимость. Коллекция установилась, а модуль падает с "No module named jmespath". Коллекции из Galaxy НЕ тянут pip-зависимости автоматически - их надо явно прописать в requirements.txt.
  • Путаешь build и create. create только генерирует Containerfile, образа не будет. Чтобы получить образ - build.
  • Кеш слоёв. Поменял requirements.yml, а версия коллекции старая - podman взял слой из кеша. Пересобирай с --no-cache, если зависимости явно обновились, а образ это игнорирует.
Мини-лаба

Повтори руками, без копипасты целиком:
  • Поставь ansible-builder через pip и проверь версию.
  • Создай каталог проекта и четыре файла: execution-environment.yml (version 3), requirements.yml с ansible.posix и community.general, requirements.txt с jmespath, bindep.txt с gcc и git-core.
  • Собери образ: ansible-builder build -t myee:1.0 -v 3.
  • Загляни в сгенерированный context/Containerfile - найди, на каком шаге ставятся коллекции и где врезались твои additional_build_steps.
  • Проверь содержимое: podman run --rm myee:1.0 ansible-galaxy collection list.
  • Запусти любой простой плейбук через ansible-navigator с этим образом.
Контрольные вопросы
  • Какие три слоя зависимостей описываются в dependencies и на какие файлы они ссылаются по умолчанию?
  • Чем отличается ansible-builder create от ansible-builder build?
  • Почему модуль из community.general может упасть с ошибкой про отсутствующий питон-модуль, даже если коллекция установилась?
  • В какие точки additional_build_steps можно врезать свои команды и зачем нужен prepend_final?
Итог

ansible-builder превращает декларативный execution-environment.yml (version 3) в воспроизводимый контейнер: три слоя зависимостей (galaxy, python, system), генерация Containerfile и сборка через podman одной командой build. Это уже не экзотика, а базовый навык современного RHCE: ansible-navigator и Automation Platform работают именно с EE-образами. Соберёшь свой EE с ansible.posix и community.general руками - и проблема "а у меня другой ansible" уходит навсегда.
👍4 ❤️1 🔥1 😄 🤔2
Аватара пользователя
sanya77
Сообщения: 1
Зарегистрирован: 28 май 2026, 08:36

Re: Сборка Execution Environment с ansible-builder

Сообщение sanya77 »

Спасибо, наконец дошло зачем нужен create отдельно от build. Раньше всегда гонял build и ждал podman просто чтобы глянуть Containerfile.
👍2 ❤️1 🔥 😄 🤔1
Аватара пользователя
prometheuslord
Сообщения: 1
Зарегистрирован: 18 май 2026, 15:30

Re: Сборка Execution Environment с ansible-builder

Сообщение prometheuslord »

Споткнулся ровно на грабле с jmespath - коллекция стоит, а модуль ругается. Дописал в requirements.txt, пересобрал, заработало. Подскажите, а как лучше версии коллекций пинить, через >= или жёстко ==?
👍2 ❤️ 🔥1 😄 🤔
Ответить
← Предыдущая глава
Execution Environments: контейнеры для запуска Ansible
Следующая глава →
ansible-navigator: запуск плейбуков в Execution Environment

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

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

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

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

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