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. Это лучше чем узнавать о несовместимостях из упавшего деплоя в пятницу вечером.
- Ansible Galaxy и роли: рефакторим монолитный playbook на части · 27 января 2015
- Ansible для Windows через WinRM: первые шаги без агента · 10 марта 2015