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

Ansible 2.0 beta: тестируем новый движок задач и готовимся к рефакторингу

Ansible 2.0 в бете меняет движок задач, синтаксис include и обработку ошибок. Проверяем обратную совместимость и начинаем рефакторинг playbooks.

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

Ansible 2.0 (бета) вводит переписанный движок задач, новый include-механизм и улучшенную обработку ошибок

Несколько дней назад в рассылке Ansible появился анонс публичной беты 2.0. Мы в тот же вечер поставили её на тестовую машину и прогнали свои playbooks - хотелось понять, насколько серьёзен разрыв с 1.9, пока до GA ещё есть время.

Коротко: обратная совместимость в основном есть, но «в основном» - это не «полностью». Несколько вещей придётся переписать. Рассказываем что нашли.

Откуда взялось желание тестировать заранее

У нас на сопровождении несколько клиентов с инфраструктурой, которую мы автоматизируем через Ansible. После январского рефакторинга на роли накопилось уже под сотню playbooks и задач. Обновить Ansible когда-нибудь потом и «посмотреть по ходу» - это рецепт ночи с debugging'ом в самый неудобный момент. Лучше посмотреть сейчас в спокойной обстановке.

Установили из pip с указанием ветки разработки, развернули на тестовом инвентаре - полную копию одного из клиентских окружений, без продакшен-хостов.

Движок задач: что поменялось под капотом

Главное изменение в 2.0 - переписанный task executor. Ansible 1.x гонял задачи через довольно запутанный код с большим количеством глобального состояния; 2.0 делает это чище. На практике это означает:

  • Параллелизм стал предсказуемее. В 1.9 при forks > 10 иногда вылезали странные гонки - переменные из одного хоста проскакивали в контекст другого. В 2.0 изоляция между воркерами жёстче. На тестах это ощущается даже субъективно - меньше непредсказуемых «changed» там где ничего не менялось.
  • Отладочный вывод стал читаемее. TASK [role-name : task-name] вместо просто TASK: - сразу видно какая роль, какой таск, не надо листать вверх в поисках контекста.
  • Обработка ошибок: при ignore_errors: yes в 1.9 иногда терялся текст самой ошибки в выводе. В 2.0 ошибка всё равно печатается, просто помечается как ignored. Мелочь, но при разборе логов это полезно.

Где сломалось

Прогнали весь набор ролей в режиме --check сначала. Большинство прошло, но несколько мест выдали предупреждения или упали.

Синтаксис with_items никуда не делся, но документация намекает на смену. В 2.0 часть with_*-итераторов объявлена deprecated в пользу унифицированного подхода - команда явно говорит, что в будущих версиях это упростят. Пока всё работает, но предупреждения в логах уже есть. Это управляемо, но у нас with_items встречается, наверное, раз сто в разных ролях - придётся планомерно менять.

include: стал более строгим. В 1.9 можно было делать динамический include внутри цикла (with_items) достаточно свободно. В 2.0 поведение изменилось: динамические include внутри циклов и с переменными-путями обрабатываются иначе, часть конструкций упала. Несколько наших вариантов вида «include разные task-файлы в зависимости от переменной» перестали работать как раньше. Там надо переписывать явно.

include_vars с wildcard - наш способ подгружать переменные из нескольких файлов в зависимости от группы хоста - в одном месте повёл себя иначе. Порядок загрузки файлов изменился, и переменная, которая должна была перекрываться более специфичным значением, загружалась в обратном порядке. Потратили час на то, чтобы это поймать.

Роль с meta/dependencies у одного из клиентов объявляла зависимость на себя же через переменную - хак, который в 1.9 просто игнорировался. В 2.0 это ловится и падает с понятной ошибкой. Правильно, но надо было убрать этот костыль ещё тогда.

Что понравилось

Анонсирована директива include_role:, которая должна позволить подключать роль из таска, а не только из верхнего уровня playbook. В нынешней бете она ещё нестабильна - команда явно пометила её экспериментальной - но направление понятно. Раньше если нужно было применить роль условно или в цикле, приходилось городить обходные пути. Когда это заработает в финале, несколько наших playbooks упростятся.

Ещё заметно улучшилась работа с become (раньше sudo). В 1.9 sudo работал, но директива become_user в отдельных сценариях вела себя неочевидно. В 2.0 это выровняли, и конфигурация повышения привилегий стала однозначной.

Что делаем дальше

Ждать GA-релиза и потом переезжать в авральном режиме - не наш вариант. Выработали план:

  • Deprecation warnings - фиксим при первой возможности. Устаревший синтаксис меняем по мере касания роли, не перекапывая всё сразу.
  • Динамические include: - аудит всех мест, где include используется внутри цикла или с переменным путём. Их немного, но каждый нужно проверить вручную - автоматически не заменишь.
  • include_role: (когда стабилизируется) - начнём использовать в новых ролях, старые не трогаем без повода.
  • Тестовый инвентарь держим на 2.0 - все новые playbooks проверяем на обеих версиях параллельно вплоть до окончательного переключения.

Примерно треть проблем уже исправлена, остальное - в процессе. Если темп не замедлится, к моменту GA будем готовы переключиться без стресса.

Отдельно радует что команда Ansible написала migration guide ещё в период беты - там покрыты основные breaking changes. Это лучше чем узнавать о несовместимостях из упавшего деплоя в пятницу вечером.

Контакт

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

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