ADG Оставить заявку
Блог Автоматизация 5 мин чтения

Обновляем AWX до версии 11: новый API, Collections и переписанные Inventories

Red Hat переносит модули из core в Collections, AWX 11 ломает Inventories API. Обновляем продакшн-стенд клиента и фиксируем, что изменилось между версиями.

Контекст момента

Ansible Collections переходят в фазу активного развития: Red Hat переносит модули из core в коллекции, AWX обновляется до версии 11 с новым API и поддержкой Collections

AWX 11 вышел в конце марта, и у одного из клиентов в рамках managed-сопровождения мы держим AWX как основной оркестратор - там десятки плейбуков, несколько инвентарей, кастомные credential types. Обновляться надо было в любом случае: версия 9, которая стояла, уже не получала исправлений. Но оказалось, что это не просто «поднять контейнеры заново». Между 9 и 11 в API Inventories что-то заметно поменялось, и это пришлось разбирать руками.

Контекст: почему именно сейчас

Red Hat активно переносит модули из ansible/ansible в отдельные коллекции. Это началось с Ansible 2.9, но сейчас, в апреле, темп ускорился: community.general, community.network, cisco.ios, amazon.aws - коллекции обрастают модулями и выходят независимые релизы. AWX 11 это учитывает: он умеет устанавливать коллекции из requirements.yml прямо в проекте, не нужно добираться до контейнера руками.

Для нашего клиента это важно - у него есть проект с зависимостью от community.vmware, которая как раз вышла из core в отдельную коллекцию. До обновления AWX это разрешалось костылём: коллекция была вручную прописана в кастомный ee-образ. После 11 - уходит в requirements.yml проекта и всё.

Как обновлялись

AWX разворачивается через operator в Kubernetes, у клиента это небольшой k3s-кластер. Сценарий апгрейда по документации выглядит прилично: обновить CRD оператора, поменять версию в CR, дождаться пересоздания подов. На практике - несколько нюансов.

Первое: база данных. AWX хранит всё в PostgreSQL, и между версиями 9 и 11 схема менялась дважды. Миграции накатываются автоматически при старте, но перед этим нужен snapshot базы - мы сделали pg_dump вручную, потому что operator в 11 не гарантирует автоматический backup перед апгрейдом. Это не баг, это просто надо знать.

Второе: isolated node. У клиента есть isolated node для запуска плейбуков в DMZ. AWX 11 обновил версию bubblewrap и поменял часть параметров запуска задач на изолированных узлах - старая конфигурация перестала работать, пришлось пересобирать isolated node заново. Это заняло отдельный час.

Третье: credentials. Кастомные credential types дошли без изменений, это хорошо. Но если credential использовал extra_vars injection с вложенными объектами - часть шаблонов слегка изменила синтаксис в UI. Визуально незаметно, но при тестировании один плейбук упал именно на этом.

Inventories API: что поменялось между версиями

Это главная боль обновления. У клиента была автоматизация на Python, которая через AWX API создавала и обновляла инвентари - добавляла хосты, группы, переменные. Скрипт был написан под AWX 9, и после обновления начал падать с 400-ми.

Разобрались. Изменения в Inventories API между 9 и 11:

  • Endpoint для групп хостов. В AWX 9 добавить группу в инвентарь можно было POST на /api/v2/inventories/{id}/groups/. В 11 этот endpoint работает иначе: он создаёт группу, но не привязывает к родительской группе в том же запросе. Для иерархических групп нужен отдельный вызов /api/v2/groups/{id}/children/.
  • Переменные хоста. Раньше переменные передавались как JSON-объект в поле variables. Теперь AWX 11 ожидает их как YAML-строку в том же поле variables - JSON тоже принимается, но при чтении возвращается уже YAML. Скрипт, который читал и сравнивал переменные через json.loads, начал падать на YAML-ответах.
  • Bulk операции. В AWX 11 появился /api/v2/bulk/host_create/ - можно создать много хостов одним запросом. Это новое, в 9 такого не было. Для нашего клиента это оказалось кстати - он создавал хосты по одному в цикле, и на больших инвентарях это было медленно.

Скрипт переписали под 11: добавили обработку YAML в variables, поправили логику создания иерархических групп, переключили bulk-создание хостов там где это уместно. Заняло полдня.

Dynamic Inventory Sources: переходим с кастомных скриптов

До обновления у клиента был кастомный inventory script на Python - он ходил во внутренний CMDB по API и возвращал JSON в формате Ansible dynamic inventory. Это старая схема, которую AWX поддерживал через Custom Inventory Scripts.

AWX 11 эту схему не убрал, но документация намекает что это deprecated-путь. Правильный способ сейчас - Custom Inventory Plugin через Collections. Мы перешли: написали inventory plugin как часть внутренней коллекции клиента (тот самый private namespace, который мы давно хотели оформить), положили в requirements.yml проекта, и AWX подтягивает его при синхронизации.

Выигрыш практический: плагин получает конфигурацию через inventory source variables в AWX UI - не нужно хранить URL CMDB и токен в скрипте. Credentials из AWX передаются в plugin через environment variables стандартным механизмом.

Где сейчас

AWX 11 у клиента в продакшне третью неделю. Isolated node в DMZ работает, коллекции подтягиваются из requirements.yml, dynamic inventory через plugin синхронизируется. Скрипт управления инвентарями переписан под новый API.

Открытый вопрос - isolated node в DMZ: сейчас один узел, и это не HA-схема. При падении узла задачи на изолированном сегменте не запускаются. Это архитектурная задача на следующий спринт.

Collections как модель распределения модулей начинает ощущаться правильной именно сейчас, когда community.vmware и community.network живут отдельно от core и версионируются независимо. Когда роль фиксирует cisco.ios==1.2.0 в requirements.yml - это другой уровень воспроизводимости, чем был год назад.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.