Ansible 4.0: ansible-core минимален, коллекции - всё остальное, requirements.yml - обязателен
Ansible 4.0 завершает переход на collections-based экосистему: ansible-core 2.11 содержит только builtin, остальное - в коллекциях с явными версиями в Automation Hub.
Ansible 4.0 выходит как полноценный релиз на основе ansible-core 2.11: монолитный ansible-пакет окончательно разбит на минимальное ядро и отдельные коллекции
В январе мы разбирали миграцию на Ansible 2.10 и коллекции: заполняли requirements.yml, расставляли FQCN, чинили AWX. Казалось - основная волна позади, дальше будет спокойнее. С выходом Ansible 4.0 выяснилось, что январская работа была разминкой.
Что изменилось в 4.0 по сравнению с 2.10
Структурно 4.0 - это тот же принцип, доведённый до логического конца. Если в 2.10 ansible как pip-пакет ещё нёс в себе часть legacy-совместимости и shim-обёртки работали для многих старых имён модулей, то теперь картина другая:
- ansible-core 2.11 - это ядро, которое идёт отдельным пакетом. Только
ansible.builtin.*: copy, template, service, file, command, shell и ещё порядка пятидесяти фундаментальных модулей. - ansible пакет версии 4.x - метапакет, который тянет ansible-core 2.11 плюс зафиксированный набор коллекций. Если устанавливаешь
pip install ansible==4.0.0, получаешь всё это вместе. Но пакет ansible и пакет ansible-core теперь версионируются независимо. - Коллекции - каждая живёт в своём цикле.
community.general3.x,amazon.aws1.x,community.postgresql1.x - всё отдельно.
Разрыв с монолитом теперь не архитектурный концепт, а факт установки. Попытка запустить плейбук с postgresql_user на голом ansible-core без нужной коллекции даёт чёткую ошибку: модуль не найден. Никакого «может прокатит».
Что это значит в практике
У клиентов, которых мы ведём в рамках managed-сопровождения, ситуация с коллекциями после января была неоднородной. Три окружения прошли полную миграцию с FQCN и requirements.yml. Остальные - частично: критичные плейбуки поправили, периферийные оставили «на потом».
Потом наступило.
Обновление до 4.0 выявило несколько классов проблем, которые в 2.10 ещё прощались:
Первое - неявные зависимости ролей. Роли из Ansible Galaxy, которые не обновлялись год-полтора, внутри используют старые имена без FQCN. На 2.10 часть из них ещё работала через compatibility layer. На 4.0 - нет. Пришлось либо форкать роли и патчить, либо искать актуальные альтернативы. В нескольких случаях нашли более свежие аналоги в том же Galaxy; в одном - написали свою небольшую роль, потому что оригинал явно заброшен.
Второе - Python-зависимости коллекций. amazon.aws 1.x требует boto3 конкретных версий. community.vmware - pyvmomi. На AWX, где Python-окружение общее для всех проектов, это начало конфликтовать. На 2.10 мы видели этот потолок, но он не давил. На 4.0 конфликт проявился явно на одном клиентском AWX с несколькими проектами разной направленности.
Третье - версии коллекций в requirements.yml без верхней границы. В январских requirements.yml у нас были записи вида version: ">=1.0.0". За полгода community.general выпустила 3.x с несколькими breaking changes внутри. При очередной синхронизации проекта AWX молча подтянул новую версию - и один плейбук с ldap_entry упал, потому что аргументы модуля поменялись.
Фиксируем версии в Automation Hub
Вывод очевидный, хотя и чуть болезненный в обслуживании: версии коллекций надо пинить. Не >=, а ==. Или хотя бы >=X.Y.0,<X.Z.0 если хочется автоматически получать патч-релизы внутри минора.
collections:
- name: community.general
version: "==3.2.0"
- name: community.postgresql
version: "==1.3.0"
- name: community.docker
version: "==1.7.0"
- name: amazon.aws
version: "==1.5.0"
- name: ansible.windows
version: "==1.6.0"
- name: community.vmware
version: "==1.11.0"
Обновление версии - осознанное действие с проверкой changelog, а не побочный эффект синхронизации проекта. Это добавляет работу при обновлениях, но убирает класс инцидентов «вчера работало, сегодня нет, AWX ничего не менял».
Для тех кто использует Automation Hub от Red Hat - там появился нормальный механизм блокировки версий на уровне организации. Если инфраструктура позволяет настроить внутренний Hub, это разумный вариант: централизованный реестр одобренных версий коллекций, один источник правды для всех AWX-инстансов.
Execution Environments: смотрим, но не переходим
Red Hat настойчиво двигает Execution Environments как замену схеме «AWX + requirements.yml». Идея понятна: образ Docker, который содержит ansible-core, коллекции и Python-зависимости вместе, решает проблему конфликтов и даёт воспроизводимость на уровне контейнера.
Мы смотрим на это со сдержанным интересом. Добавить в пайплайн сборку кастомного EE-образа - это отдельный инфраструктурный проект с registry, CI и процессом обновления. Для одного-двух клиентов с простыми плейбуками овчинка не стоит выделки. Для клиента с vmware + aws + нестандартными Python-либами - да, это выглядит как правильное направление.
Пока остаёмся на requirements.yml с пиннингом версий. Схема работает, поведение предсказуемо, проблема Python-конфликтов на том конкретном AWX решена разделением проектов по отдельным виртуальным окружениям - не элегантно, но работает.
Итог
Ansible 4.0 не принёс неожиданных архитектурных сюрпризов - он добил то, что анонсировалось с 2.10. Монолит распался окончательно, коллекции стали единственным способом добавить что-то выходящее за рамки builtin. Для тех кто провёл миграцию в январе-феврале - апгрейд прошёл без драмы. Для тех кто откладывал - драма была, просто теперь, а не потом.
Практическое правило, которое вынесли из этого цикла: requirements.yml с зафиксированными версиями коллекций - не опция, а обязательный артефакт любого Ansible-проекта. Хранится в git, обновляется явно, проходит ревью.