# Summary: Ansible playbook для настройки площадки A **Дата:** 2026-09-03 **План:** [2026-09-03-ansible-site-a-plan.md](2026-09-03-ansible-site-a-plan.md) ## Что сделано Создан `ansible/` — playbook + роль `frr_anycast` для конфигурации FRR на ВМ площадки A (a1/a2/a3). Provisioning ВМ (3 NIC: 1 внешний + 2 приватных) — Terraform, вне рамок этой задачи; playbook создаёт только `dummy0` (netplan) и разворачивает FRR. **Параметризация подтверждена практически, а не только на словах**: единственный источник site-A-специфичных значений — `ansible/site-a.env` (плоский `KEY=VALUE`). Цепочка `env → group_vars/site_a.yml + host_vars/a{1,2,3}.yml (lookup('env', ...)) → роль frr_anycast → шаблоны` — ни один IP/ASN/router-id не захардкожен ни в роли, ни в `frr.conf.j2`/`daemons.j2`/`dummy0.netplan.yml.j2`. Ansible оказался уже установлен системно (core 2.14.18) — venv по плану не потребовался (сценарий с `python3 -m venv venv` реализован в `run.sh` как fallback, но не задействован). `ansible-lint` не установлен и не устанавливался — по плану опционален. ## Отклонения/уточнения в процессе реализации 1. **`ERROR: Ansible requires blocking IO`** — известное ограничение ansible-playbook в этом sandboxed-окружении при прямом запуске из Bash-тула; решается пайпом через `cat` (`... 2>&1 | cat`). Учтено в `render-check.sh`. 2. **`group_vars`/`host_vars` не подхватились в тестовом плейбуке** — Ansible ищет их относительно каталога *переданного* playbook'а и inventory-файла; `ansible/tests/render-test.yml` лежит в подкаталоге `tests/`, поэтому `ansible/group_vars`/`ansible/host_vars` не попадали в scope автоматически. Продакшн-playbook `ansible/site-a.yml` (лежит прямо в `ansible/`) эту проблему не имеет — переменные подхватываются штатно. Для теста добавлены явные задачи `include_vars`. 3. **`daemons.j2` переписан без Jinja-цикла** — изначальный вариант с `{% for %}` рисковал дать лишние пустые строки при рендере (поведение `trim_blocks`/`lstrip_blocks`), а набор демонов не site-специфичен (одинаков на всех A-нодах) — статичный текст безопаснее и предсказуемее. ## Результаты проверки (без живых ВМ — они не подняты) - `ansible-playbook --syntax-check` — OK. - **`ansible/tests/render-check.sh`** — golden-diff рендера `frr.conf.j2`/`daemons.j2` для a1/a2/a3 против уже подтверждённых живыми BGP-сессиями (10/10 Established, 3-way ECMP — см. `docs/2026-09-03-anycast-lab-summary.md`) `frr/a{1,2,3}/{frr.conf,daemons}`: - `daemons` — совпадает побайтово для всех трёх узлов. - `frr.conf` — совпадает полностью, за вычетом блока `interface dummy0` (осознанно вынесен в netplan, см. Context плана) — единственное различие подтверждено и является дизайн-решением, а не ошибкой. - Синтаксис Jinja-шаблона netplan (`dummy0.netplan.yml.j2`) проверен рендером с тестовыми значениями и парсингом через `yaml.safe_load` — валиден. ## Известное ограничение Реальный apply (`apt install frr`, `netplan apply`, `systemctl restart frr`) и функциональная проверка (`show bgp summary` и т.д. на живых ВМ) не выполнялись — ВМ площадки A ещё не подняты Terraform-слоем. Это нужно сделать вручную после провижининга (команды — в README, раздел «Развёртывание площадки A на ВМ»). ## Изменённые/новые файлы - `ansible/` — вся структура (site-a.env, run.sh, ansible.cfg, inventory/, group_vars/, host_vars/, site-a.yml, roles/frr_anycast/, tests/). - `.gitignore` — новый (`venv/`, `*.retry`). - `README.md` — новый раздел «Развёртывание площадки A на ВМ (Ansible)». - `docs/2026-09-03-ansible-site-a-plan.md`, `docs/2026-09-03-ansible-site-a-summary.md`.