Ansible 2.2: переписываем библиотеку ролей под стабильный include_role
Ansible 2.2 вышел стабильным в октябре. Закрепляем практики: galaxy-совместимая структура ролей, тесты через molecule, конец самописным shell-обёрткам.
Ansible 2.2 стабилен - include_role из экспериментального стал рабочим, появились network-модули для оборудования
Ansible 2.2 вышел в октябре и несколько недель мы не торопились переезжать. Не из осторожности - просто ноябрь и декабрь ушли на другое. В январе сели и разобрались, и теперь часть того, что копилось как технический долг, наконец списана.
Что изменилось в 2.2, что важно нам
Главное - include_role перестал быть помечен как experimental. В превью 2.0 мы описывали эту директиву как «направление понятное, но трогать рано». В 2.1 она поехала работать, в 2.2 команда убрала предупреждение и задокументировала поведение. Это меняет структуру playbooks: роль теперь можно вызвать из task-файла, передать ей переменные и условие, не вынося логику на верхний уровень.
Второй блок - network-модули. В 2.2 вошла первая партия: ios_command, ios_config, eos_*, junos_*. Мы работаем с Cisco на нескольких объектах, и до этого настройка оборудования через Ansible означала либо raw, либо свою обёртку вокруг expect. Это было мерзко и хрупко. С ios_config всё стало по-человечески: идемпотентно, с diff, без магии с промптами.
Что именно переписали
Библиотека ролей у нас накопилась за три года. В 2015-м делали рефакторинг под Galaxy-совместимую структуру, но часть старых ролей так и осталась в виде «исторически сложившихся» плейбуков с жёстко прописанными путями и переменными в vars/ вместо defaults/. Плюс несколько shell-скриптов которые вызывались из command: потому что в своё время нормального модуля не было.
Прошлись по всему. Итог:
- Shell-обёртки под сетевое оборудование - убрали полностью. Заменили на
ios_configс шаблонами. Три скрипта, которые работали черезexpectи падали при малейшем изменении прошивки, теперь не существуют. - Роли с переменными в
vars/- перенесли вdefaults/. Это мелочь, но была причина почему несколько ролей нельзя было параметризовать снаружи без хаков. Теперь можно. - Условная логика через
when+include:- переписали наinclude_roleс передачей переменных черезvars:. Стало читаемее.
Структура каждой роли теперь выглядит стандартно:
roles/
nginx/
defaults/
main.yml
tasks/
main.yml
handlers/
main.yml
templates/
nginx.conf.j2
meta/
main.yml
molecule/
default/
playbook.yml
tests/
test_nginx.py
Это galaxy-совместимая структура - если когда-нибудь захочется опубликовать роль, добавлять ничего не придётся.
Molecule: тесты для ролей
До этого тестирование ролей у нас выглядело как «запустил на стенде, посмотрел что не сломалось». Molecule 1.x появился ещё в 2015-м, но мы смотрели на него скептически - казалось лишним слоем. Сейчас добавили в несколько критичных ролей.
Схема простая: molecule поднимает Docker-контейнер с нужной ОС, прогоняет роль, потом запускает testinfra-тесты. Тест проверяет что нужный сервис запущен, конфиг сгенерировался с правильными значениями, нужные порты открыты. Не то чтобы полная имитация продакшена - контейнер это не железный сервер - но большинство ошибок в ролях это синтаксис и логика, а не окружение.
# roles/nginx/molecule/default/tests/test_nginx.py
def test_nginx_running(host):
nginx = host.service("nginx")
assert nginx.is_running
assert nginx.is_enabled
def test_nginx_config(host):
config = host.file("/etc/nginx/nginx.conf")
assert config.exists
assert config.contains("worker_processes")
Добавили это в шесть ролей, которые меняются чаще всего. Остальные - по мере касания.
Про network-модули честно
ios_config работает, но с оговорками. Idempotency там не бесплатная: модуль сравнивает конфиг с тем что уже есть на устройстве, и это иногда даёт ложные «changed» из-за того как IOS форматирует output. На двух устройствах пришлось добавить diff_ignore_lines чтобы убрать шум. Не критично, но надо знать заранее.
ios_facts для сбора инвентаря работает хорошо - теперь можно получить версию прошивки, список интерфейсов и serial number прямо в playbook без отдельного скрипта.
Где сейчас
На сопровождении около восьмидесяти хостов плюс несколько единиц сетевого оборудования. После переработки ролей прогон базового харденинга стал чище - меньше шумных «changed» по уже настроенным параметрам. Network-часть пока на двух объектах, смотрим как ведёт себя в штатном режиме.
Molecule в CI пока не добавили - это следующий шаг. Сейчас тесты запускаются руками перед коммитом роли, что лучше чем ничего, но не идеально. Интеграция с GitLab CI в очереди.
Технический долг не исчезает, он накапливается медленнее если разбирать его порциями. Январь выдался подходящим для этого месяцем.
- Ansible Galaxy: берём роли с полки вместо написания с нуля · 30 октября 2015
- Ansible 2.0 beta: тестируем новый движок задач и готовимся к рефакторингу · 12 мая 2015