InquirerMarcos swears in Zalameda as chief justicePunchEx-Kwara ADC spokesperson defects to APCThe Jerusalem PostGunman behind deadly Krakow mass shooting dies in hospital as investigation into motives continues한겨레지역 유일 상급종합병원 울산대병원 노조 “구조조정 중단하라”N + 1Океан стал синее и зеленее вблизи Большого мусорного пятнаZDF heuteAktuelle Pressemitteilungen des ZDFObservador DesportoTrump admite provável encontro com Xi e Putin na ChinaRFI 中文日本国家安保战略将不提中国“威胁”只提“挑战”سكاي نيوز عربيةأبوظبي تشهد رقما قياسيا عالميا لسيارة BYD الكهربائية الخارقةEuronewsTrump calls Nvidia chief Jensen Huang an 'honorable guy' amid spy allegationsDaily MailThey fought for their country. Their reward? Euthanasia. Veterans with serious injuries or PTSD reveal they are being invited to end their lives under Canada's assisted dying systemBBC News BrasilAtirador mata 6 em praça no centro de Cracóvia, na Polônia, e morre após confronto com a polícia
The Daily Newsstand · Free, Always
Monday, November 9, 2026

Почему в Ansible так тяжело разруливать отказы, и как я написал Flow Designer для VS Code

Translate
Ansible Flow Designer

Ansible Flow Designer

Пока в Ansible всё идёт по плану, плейбуки пишутся легко. Сложности начинаются на десятках реальных устройств, когда на каждом шаге часть хостов отваливается: из 60 коммутаторов два не прошли предпроверку по памяти, один завис при перезагрузке по SSH (unreachable), ещё три выдали ошибку при заливке прошивки — их нужно срочно откатить к бэкапу и отправить тикет в NOC, а остальные 54 должны спокойно дойти до конца. Если пытаться обработать все эти ситуации средствами самого Ansible, плейбук быстро разрастается. Появляются вложенные block / rescue, group_by, дополнительные переменные через set_fact и условия when. В какой‑то момент становится сложнее разобраться в обработке ошибок, чем в самих задачах.

Мне надоело собирать эту обвязку вручную, и я написал Ansible Flow Designer — опенсорсное расширение для VS Code. С помощью расширения можно собрать схему выполнения плейбука, настроить обработку ошибок для отдельных групп хостов и проверить результат во встроенном симуляторе. На выходе получается обычный Ansible‑код, который можно запускать через CLI, CI/CD или AWX. Под катом — как устроена модель потоков, как кодогенератор обходит ограничения ядра Ansible и как тестировать аварийные сценарии без боевого стенда.

По проводам текут хосты

В привычных оркестраторах вроде Airflow, Prefect или GitHub Actions узел графа — это неделимая задача: скачал архив → распаковал → загрузил в БД. Шаг либо выполнился, либо упал целиком.

В Ansible каждый шаг выполняется над множеством хостов инвентаря, и после выполнения это множество распадается на части. Например, раскатываем базовый конфиг на 40 коммутаторов:

  • 37 отработали штатно (ok_hosts);

  • 2 вернули ошибку модуля (failed_hosts);

  • 1 не уложился в таймаут задачи (timeout — если этот порт включён в настройках шага; по умолчанию порты unreachable и timeout выключены, чтобы не перегружать схему).

В зависимости от результата выполнения задачи хосты переходят на разные следующие шаги. Например, устройства, на которых не прошла предпроверка, можно отправить на отдельную ветку, а остальные продолжат выполнение плейбука.

Проектирование сверху вниз

Схему не обязательно начинать с подбора конкретных модулей (ios_config, cisco.ios.ios_l2_interfaces или template).

Сначала можно набросать крупные этапы через подпотоки (Subflows): «1. Precheck & Drain» → «2. Push Firmware & Baseline» → «3. Postcheck & Health», а с портов ошибок сразу увести ветки в «Rollback & Recovery».

Смоделированный прогон на 12 свитчах для демонстрации маршрутизации

Смоделированный прогон на 12 свитчах для демонстрации маршрутизации

Даже на этом верхнем уровне схема уже привязана к семантике Ansible: у блоков есть таргеты инвентаря, порты исходов и политики выполнения. Получается рабочий каркас, внутрь которого можно провалиться позже и наполнить шаги модулями или ролями.

Кодогенерация: как обойти ограничения Ansible Core

Когда я садился за генератор (ADR-0003, ADR-0009), идея казалась тривиальной: оборачиваем задачу в block/rescue, успешные хосты складываем в группу flow_step_ok, упавшие — в flow_step_failed.

Но на тестах с ansible-core 2.19–2.21 сразу вылезли две особенности движка:

  1. rescue не ловит unreachable‑хосты. Если узел перестал отвечать по сети, Ansible просто вычёркивает его из прогона — в секцию отката он не попадёт.

  2. Если в каком‑то play упали все входящие в него хосты, ansible-playbook останавливает весь плейбук целиком. То есть следующий независимый play с откатом, сбором дампов или отправкой алерта дежурному даже не запустится.

Поэтому кодогенератор построен вокруг простого правила: внутри рабочих play ни один хост не должен ронять плейбук.

Каждый узел схемы компилируется в отдельный play. Для модульных шагов генератор выставляет ignore_unreachable: true, а задачи оборачивает в block / rescue, раскладывая хосты по динамическим группам flow_<node>_<port>. Вот реальный фрагмент сгенерированного кода для шага с вызовом роли:

- name: "[push-baseline] Push baseline"
  hosts: flow_backup_config_ok_hosts
  gather_facts: false
  tags: [node_01JBDJ8FSSZ5AWSH8VHTPRE95B]
  vars:
    flow_node_id: 01JBDJ8FSSZ5AWSH8VHTPRE95B
    backup_ref: "{{ afd_backup_config__backup_ref }}"
  tasks:
    - block:
        - name: "[push-baseline] Apply role"
          ansible.builtin.include_role:
            name: netops.baseline.push_ntp_aaa
            apply:
              tags: [node_01JBDJ8FSSZ5AWSH8VHTPRE95B]
        - name: "[push-baseline] route ok_hosts"
          ansible.builtin.group_by:
            key: flow_push_baseline_ok_hosts
      rescue:
        - name: "[push-baseline] route failed_hosts"
          ansible.builtin.group_by:
            key: flow_push_baseline_failed_hosts

Ограничение для ролей (ADR-0009): для шагов‑модулей перехват unreachable работает поштучно для каждого хоста. Но если шаг вызывает роль (include_role, как в примере выше) или вложенный плейбук, ядро Ansible не даёт перехватить сетевую недоступность в середине роли. Потерянный хост выбывает из прогона по стандартным правилам Ansible, а если недоступными стали сразу все хосты такого шага — плейбук остановится. Поэтому сетевые проверки перед тяжёлыми ролями лучше выносить в отдельные модульные шаги.

Статус прогона в CI/CD (Outcome Play)

Если рабочие шаги перехватывают ошибки и не падают с fatal error, нужно как‑то сообщить CI/CD или AWX, что прогон завершился со сбоем.

Для этого компилятор добавляет в самый конец файла Outcome Play. Он собирает все хосты, которые пришли на терминальные узлы сбоя или остановились на неподключённых портах ошибок, и явно валит их через ansible.builtin.fail:

fatal: [edge-sw-02]: FAILED! => {"msg": "Ended at [failed] Failed (outcome: failed)"}

(или "msg": "Stopped at [validate] Validate: failed_hosts is not wired", если порт ошибки оставили висеть в воздухе).

За счёт этого:

  • Все ветки отката, сбора логов и отправки алертов успевают доработать до конца.

  • Пайплайн в GitLab/GitHub Actions или джоба в AWX завершается с ненулевым кодом, если есть проблемные хосты.

Сам сгенерированный плейбук складывается в generated/ рядом со схемой и выполняется обычным ansible-playbook. Когда вы запускаете поток из VS Code, расширение просто подцепляет свой callback‑плагин, чтобы в реальном времени подсвечивать движение хостов по узлам графа.

Общий вид холста автоматизации в дизайнере

Общий вид холста автоматизации в дизайнере

Что есть в самом редакторе

1. Шаблоны обработки отказов

Об обработке ошибок в плейбуках часто вспоминают в последний момент. В дизайнере у каждого шага есть янтарный порт failed_hosts. Пока он никуда не подключён, сверху висит напоминание: «What should happen when „“ fails?» (интерфейс расширения на английском).

Баннер открытых портов отказов

Баннер открытых портов отказов

По клику на порт можно выбрать готовый шаблон:

  • Rollback from Backup — собирает подпоток отката (subflow) с шагами компенсации в обратном порядке (LIFO) и финальным узлом сбоя.

  • Notify On‑Call and Stop — добавляет заготовку задачи оповещения дежурного и узел остановки.

  • Exclude and Report — исключает сбойные хосты из дальнейших шагов и фиксирует их в отчёте.

  • Retry (для шагов, привязанных к модулю) — включает повторы на самом шаге (по умолчанию 3 повтора, то есть до 4 попыток суммарно, с интервалом 10 с).

  • Accept with Reason… — позволяет явно оставить порт открытым, записав причину и вашего Git‑автора в YAML. После этого предупреждение пропадает.

Меню типовых паттернов обработки отказов

Меню типовых паттернов обработки отказов

Большинство шаблонов создают на холсте каркасные заготовки (draft steps), которые затем остаётся привязать к нужным модулям или ролям.

2. Запуск черновика (Walking Skeleton)

Схему можно прогнать ещё до того, как написаны роли и подобраны параметры модулей.

Достаточно набросать узлы с описанием намерений (Intent: «Снять с балансировщика», «Проверить контрольные суммы») и нажать Run as Skeleton. Дизайнер скомпилирует плейбук и запустит его с флагом --check на хостах инвентаря или на localhost. Непривязанные шаги отработают как debug‑заглушки, а привязанные вызовут свои модули в check‑режиме (стоит помнить стандартный нюанс Ansible: если внутри роли у задачи жёстко прописано check_mode: false, она выполнится по‑настоящему).

Так можно проверить, что хосты правильно переходят между узлами, ещё до того, как готовы все роли и параметры модулей.

3. Индекс модулей из вашего контейнера и передача переменных через @

В расширении нет зашитой базы модулей. В фоновом режиме оно опрашивает ваш Execution Environment (контейнер Docker/Podman) или WSL через ansible-doc и строит полнотекстовый индекс SQLite FTS5 в локальном кэше на диске.

При поиске учитываются не только совпадения по названию и описанию модуля. Дополнительно учитываются ansible_network_os, установленные в проекте коллекции и встроенные модули. Для ранжирования используется BM25. Документация, типы параметров и возвращаемые поля отображаются прямо в панели свойств шага.

Привязка шага к модулю из каталога окружения

Привязка шага к модулю из каталога окружения

Передача данных между шагами тоже изолирована:

  • В обычном Ansible переменные из register живут в глобальном скоупе хоста — их легко случайно перетереть на следующем шаге или словить undefined, если шаг‑источник был пропущен по when.

  • В дизайнере достаточно нажать @ в поле аргумента и выбрать выход одного из предыдущих шагов. Источник сохранит результат в переменную с отдельным именем afd_<step>__<output>, а принимающий шаг прочитает её через локальный vars: своего play. При этом валидатор графа проверяет все входящие маршруты и заранее подсвечивает риск ref-may-be-undefined, если хост может прийти в узел в обход шага‑источника.

4. Сверка схемы и кода (Drift Detection)

Если кто‑то изменил код роли в репозитории или поправил файлы вручную, режим Code Mode разбирает задачи через движок Playbook.load и показывает расхождения со схемой:

  • Роль перестала возвращать переменную, которую ждёт схема.

  • В роли появились новые задачи, не отражённые на графе.

  • На схеме добавлен шаг, для которого ещё нет роли — кнопка Generate stub сгенерирует каркас роли вместе с meta/argument_specs.yml.

Режим сверки схемы и кода

Режим сверки схемы и кода

5. Шесть линз (Lenses) для анализа графа

В верхнем тулбаре есть переключатель Lenses, который меняет раскраску узлов и выводит поверх графа дополнительные данные:

  • Inventory — какие группы инвентаря доходят до каждого узла (сразу предупредит, если в ветке отката случайно написали hosts: all вместо группы упавших устройств).

  • Data — рисует пунктирные линии передачи переменных между шагами.

  • Code — проверяет статус коллекций и их наличие в requirements.yml.

  • Access — показывает, где включён become, под какими пользователями выполняются задачи и где читаются секреты Ansible Vault.

  • Timing — считает критический путь по статистике прошлых запусков и сверяет его с заданным окном работ (maintenance_window).

  • Changes — строит diff с изменениями схемы относительно выбранного Git‑коммита или ветки (подсвечивает добавленные, удалённые и изменённые узлы без шума от сдвинутых координат).

Линза Data:  отображение связей между переменными

Линза Data: отображение связей между переменными

Линза Access: подсветка become и учетных данных

Линза Access: подсветка become и учетных данных

6. Защита при ручном запуске (Run Safety)

Перед стартом на живом инвентаре диалог запуска проверяет таргеты, явно предупреждает, если в выборку попали группы вроде prod, production, prd или live, и пишет историю запусков в локальный аудит‑лог.

7. Экспорт в draw.io, SVG и PNG

Схему можно отдать тем, кто не работает в VS Code:

  • draw.io (.drawio) — каждый уровень на отдельной странице, подпотоки ссылаются на свои страницы, а детали шагов (привязка к модулю, входы и выходы, настройки, открытые порты отказов) лежат в данных фигур (Ctrl+M в draw.io).

  • SVG и PNG — для вики, тикета или слайда, один уровень или все сразу. Картинки сохраняются как .drawio.svg / .drawio.png: обычный просмотрщик покажет изображение, а draw.io откроет тот же файл как редактируемую диаграмму со всеми уровнями.

Источником правды остаётся .flow.yaml: правки в draw.io обратно в схему не возвращаются, после изменений экспорт просто повторяют. ИИ‑агент умеет экспортировать сам — через MCP‑инструмент flow_export (draw.io и SVG).

Сценарные тесты — быстрая симуляция сбоев

Отдельные ветки обработки ошибок проверить несложно. Проблемы начинаются, когда нужно проверить несколько отказов одновременно и убедиться, что каждый хост попадёт в нужную ветку. На реальном оборудовании такие тесты проводить неудобно. В Flow Designer рядом со схемой можно хранить файл со сценариями <flow>.scenarios.yaml (ADR-0026), который задаёт отказы конкретных шагов и проверяет, в каких узлах должны оказаться хосты:

flow: pool-health-check
scenarios:
  - name: "A balancer whose peer is out of sync is reported to the NOC"
    inputs:
      devices: [lab-lb-44, lab-lb-45, lab-lb-46]
    force:
      check-the-peer-is-in-sync:
        failed: [lab-lb-46]    # имитируем сбой шага только на одном устройстве
    expect:
      lab-lb-44: done
      lab-lb-45: done
      lab-lb-46: reported-to-noc   # сбойный хост должен прийти в узел репорта NOC

Писать этот YAML вручную не нужно — сценарии собираются кликами мыши на холсте:

  1. Запись сценария (What‑If). Кнопка New Scenario в боковой панели сценариев сохраняет текущие маршруты хостов как эталонные ожидания (expect).

  2. Ввод отказов из контекстного меню. Кликаем правой кнопкой по шагу → «In „„„ → выбираем исход (Fail for…, Unreachable for…, Time Out for…) и отмечаем галочками хосты. Для узлов ветвления (Decision) можно принудительно задать Take False, а для согласований (Approval) — Rejected или Timed Out. Холст сразу перестраивает маршрут. Если новая траектория верная, кнопка Accept New Ends обновляет expect в YAML. “““»

    Моделирование сбоев на шаге из контекстного меню

    Моделирование сбоев на шаге из контекстного меню

  3. In‑Memory симулятор (ADR-0032). Гонять контейнеры с Ansible на каждый чих долго. Поэтому компилятор строит в памяти план выполнения (RunPlan), а встроенный симулятор просчитывает движение пулов хостов без вызова Python или Docker. Проверка перезапускается автоматически через 200 мс после любой правки графа. Если вы случайно переключили провод не туда, VS Code сразу подсветит сломанный сценарий: «lab‑lb-46 now ends at Stopped; expected Reported to NOC».

    Сверка симулятора с реальным Ansible: чтобы in‑memory движок не расходился с настоящим ansible-core, в проекте крутится дифференциальный тестовый сьют. Более 100 схем (включая 60 сгенерированных фаззером) прогоняются параллельно в симуляторе и в контейнерах ansible-core 2.19–2.21 — результаты должны совпадать до каждого хоста. Если в схеме используются конструкции, которые нельзя точно смоделировать в памяти (serial с max_fail_percentage, паттерны хостов вместо точных имён в таргетах, Jinja‑выражения в именах или дефолтах), сценарий помечается как best effort и требует проверки в реальном Ansible.

  4. Панель тестирования VS Code и CI‑раннер. Сценарии отображаются в стандартном Test Explorer с двумя профилями запуска: Check (simulated) для быстрой проверки в памяти и Verify in Ansible для прогона сгенерированного плейбука со стабами в контейнере или WSL (при изменении графа прошлый вердикт реального прогона помечается как out of date). При переименовании узлов или выносе шагов в подпоток (Extract into Subflow) ключи шагов в сценариях обновляются автоматически. А в CI/CD тесты запускаются утилитой node .afd/afd-scenarios.js (с флагом --simulate или в боевом контейнере EE) с выгрузкой JUnit XML.

    Интеграция с панелью тестирования в VS Code

    Интеграция с панелью тестирования в VS Code

Вкладка Scenarios на холсте и симулированный маршрут

Вкладка Scenarios на холсте и симулированный маршрут

Инженерные детали

1. Сохранение YAML байт‑в-байт (Byte‑Preserving)

Частая проблема визуальных редакторов — сдвинул блок на пару пикселей, сохранил файл, и git diff показывает 400 строк переформатированного YAML со слетевшими комментариями.

В Flow Designer вебвью холста не правит текст напрямую, а отправляет только интенты (moveNodes, connect) в единый хост‑писатель (ADR-0001). Движок на базе библиотеки yaml точечно патчит AST документа: комментарии, стиль кавычек и отступы сохраняются байт‑в-байт, координаты лежат в секции layout:, а любое действие отменяется штатным Ctrl+Z.

2. MCP‑сервер для ИИ‑ассистентов

Когда просишь LLM написать сложный плейбук напрямую, модель часто ошибается в отступах, выдумывает параметры модулей или теряет ветки rescue.

В расширение встроен MCP‑сервер (Model Context Protocol) (ADR-0017). ИАгент работает со схемой через типизированные операции: add_node, connect, apply_pattern и инструмент тестирования flow_scenarios:

  • Copilot в VS Code получает эти инструменты сразу, без какой‑либо настройки.

  • Встроенные агенты форков тоже получают их от самого расширения: Cursor — автоматически через свой API, Kiro, Antigravity IDE и Devin Desktop (бывший Windsurf) — после одного клика в уведомлении.

  • Консольные агенты (Claude Code, Codex, Gemini CLI, OpenCode, GitHub Copilot CLI) подключаются командой Set Up AI Assistants…: она регистрирует MCP‑сервер и кладёт навык ansible-flow туда, где агент его ищет.

ИИ-ассистент правит схему через структурированные операции MCP (Правая панель ассистента отрисована для иллюстрации, обмен командами с MCP-сервером реальный)

ИИ‑ассистент правит схему через структурированные операции MCP (Правая панель ассистента отрисована для иллюстрации, обмен командами с MCP‑сервером реальный)

Каждый вызов агента проходит через тот же валидатор схемы, что и действия пользователя. Невалидные изменения отклоняются, а предупреждения (например, о незакрытом порте ошибки) возвращаются модели вместе с подсказкой, как их исправить.

3. Особенность «retries + 1» в Ansible Core

В настройках ожидания шага (retries и delay) интерфейс показывает расчётное время, например: «Tries up to wait_tries + 1 times (41 with its default 40), 15 s apart, …».

Когда я разбирал task_executor.py в ядре ansible-core (2.19+), обнаружилась неочевидная деталь: Ansible сначала делает один обычный запуск задачи, и только при неудаче начинает отсчитывать retries повторов. То есть в реальности задача выполняется до retries + 1 раз (ADR-0031). Дизайнер учитывает эту единицу во всех формулах расчёта таймаутов и в подсказках UI.

Пара практических примеров

  • Параметры таймаутов при запуске (Ask at Run Time). Допустим, нужно снять ноды с балансировщика, дождаться сброса активных сессий и обновить сервис, а время ожидания дренажа должен задавать дежурный при старте (по умолчанию 300 с). Вместо ручного написания формул retries: "{{ (wait_sec | int) // 10 }}" и синхронизации с AWX, в дизайнере достаточно нажать Ask at Run Time… на поле Delay/Timeout. Расширение само создаст входной параметр схемы, привяжет его к шагу и пробросит в диалог запуска и survey для AWX.

Настройка таймаутов, передаваемых во время запуска

Настройка таймаутов, передаваемых во время запуска

  • Ревизия старого плейбука на 1500 строк. Если достался монолитный site.yml и нужно понять, на каких шагах сбой оставит систему в полуразрушенном состоянии, команда Import Ansible Playbooks… за пару секунд строит по нему граф. Верхний баннер сразу покажет все необработанные места (например, «14 open fail ports»).

Импорт легаси-плейбука в наглядный подпоток

Импорт легаси‑плейбука в наглядный подпоток

  • Визуальное код‑ревью. Вместо чтения простыни сгенерированного YAML ревью пул‑реквеста можно проводить по компактному diff файла .flow.yaml и через линзу Changes, которая наглядно подсвечивает добавленные шаги и изменившиеся маршруты.

Линза Changes: наглядное сравнение схемы с предыдущим коммитом

Линза Changes: наглядное сравнение схемы с предыдущим коммитом

Сравнение с другими инструментами

Инструмент

Уровень абстракции

Источник правды

Обработка отказов

Сверка с кодом

Среда выполнения

Ansible Flow Designer

Внутри плейбука (шаги, ветвления, отказы)

*.flow.yaml в Git

Явные порты у каждого шага, автогенерация rescue/outcome

Сверка через Playbook.load

Локально в VS Code, без серверов

Red Hat Extension + Lightspeed

Текстовый YAML‑редактор

Текст плейбука

Пишется вручную в коде

Нет

Локально в VS Code

AWX / AAP Workflow Visualizer

Между Job Templates (крупные джобы)

База данных AWX (PostgreSQL)

Связи On Failure между шаблонами

Нет

Серверный кластер AWX / AAP

ansible‑playbook‑grapher

Готовый плейбук целиком

Текст плейбука

Только визуализация

Нет

CLI‑утилита

Semaphore / Rundeck

Оркестрация готовых заданий

БД оркестратора

Перезапуск задания (Semaphore) / обработчики шагов (Rundeck)

Нет

Выделенный сервер

  • В связке с AWX Workflow Visualizer: AWX связывает между собой крупные шаблоны заданий (Job Templates), но не управляет ветвлением внутри плейбука. Flow Designer работает на уровне шагов внутри плейбука, а при необходимости сам создаёт в AWX workflow со штатными Approval‑нодами.

  • В связке с расширением Red Hat: плагины дополняют друг друга — Flow Designer подхватывает настройки окружения Red Hat (Execution Environments, пути к интерпретаторам) для каталога модулей и локальных запусков.

Ограничения проекта

  • Поддерживаемые редакторы: VS Code 1.94+ и форки, которые ставят расширения из Open VSX (или из VSIX с GitHub Releases). Проверено в Cursor, Kiro, Antigravity IDE и Devin Desktop (бывший Windsurf): дизайнер открывает схемы, а встроенный ИИ‑агент каждого из них находит потоки и правит их через MCP. Каталогу модулей нужен Node.js 22.13 внутри редактора (VS Code 1.101+, во всех перечисленных форках он есть), инструментам Copilot — VS Code 1.95+. MCP‑сервер также работает автономно из консоли (например, в связке с Claude Code).

  • Пакетное выполнение (serial и Rolling): так как каждый узел компилируется в отдельный play, обычный serial работает в рамках одного шага. Чтобы провести пачку хостов (например, по 5 коммутаторов) через цепочку шагов от начала до конца перед стартом следующей пачки, нужно объединить эти шаги в Rolling‑подпоток (settings.rolling).

  • Требования к Ansible: для запуска плейбуков и индексации модулей нужен ansible-core 2.19+ (в контейнере Docker/Podman EE, WSL или локальном Python). Рисовать схемы, гонять in‑memory симулятор и генерировать код можно вообще без установленного Ansible.

  • Роли и unreachable: как описано в разделе кодогенерации, внутри include_role ядро Ansible не позволяет перехватывать сетевую недоступность по отдельным хостам.

  • Накладные расходы на число play: изоляция каждого узла в собственный play добавляет небольшой оверхед на инициализацию по сравнению с монолитным плейбуком из одного play.

  • Приоритет схемы над generated/: сгенерированные файлы не рассчитаны на постоянную ручную правку. Если изменить их руками, генератор сохранит правки и покажет конфликт, но первичным источником остаётся .flow.yaml.

  • Статус проекта: версия 0.75, проект развивается одним мейнтейнером.

Тестирование

Чтобы кодогенератор и симулятор работали предсказуемо, проект покрыт тестами на нескольких уровнях:

  • 1088 unit‑тестов (покрытие 95% строк в core и 68.6% выражений по всему проекту);

  • 90 интеграционных тестов расширения VS Code — тот же набор прогоняется на минимальной поддерживаемой VS Code 1.94 и внутри Kiro, Antigravity IDE и Devin Desktop;

  • 447 контрактных тестов движка на контейнерах с реальным ansible-core 2.19–2.21;

  • 14 сквозных тестов MCP‑сервера;

  • 4 раунда юзабилити‑тестов: практические сессии с инженером на тестовом репозитории по сценариям A‑D. Оценка по шкале SUS (System Usability Scale) по мере доработки интерфейса выросла с 30 до 82.5 баллов (30 → 75 → 65 → 82.5; по одной сессии на раунд для отлова UX‑проблем).

Как попробовать

Проект открыт под лицензией MIT:

Для быстрого старта после установки:

  1. Откройте панель Ansible Flows слева в VS Code.

  2. Нажмите Open Sample Flow… → Hello, Ansible.

  3. Если нужно настроить контейнер с ansible-core, вызовите команду Set Up Ansible Environment…, после чего пример можно сразу запустить в check‑режиме на localhost.

Пример Hello, Ansible в дизайнере

Пример Hello, Ansible в дизайнере

Если попробуете расширение, буду рад узнать, как оно работает на ваших плейбуках. Особенно интересны реальные сценарии обработки отказов и откатов, которые вы используете в своей инфраструктуре.

View the original on Хабр →

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.