Files
CloudRouterAdvanced/docs/changes/2026-09-03-adaptive-router-vm-count-summary.md
T
ayurishchevandClaude Sonnet 5 5979a9a58b Add adaptive router VM/interface scaling and local delivery integrity tests
Terraform now provisions router_count IaaS Router VMs (default 2, no
longer hardcoded to router1/router2), each with 1 public +
private_interface_count isolated private interfaces (no shared LAN or
VRRP between routers). Both counts scale via Terraform variables and
TF_VAR_* environment variables. The post-install script became a
Terraform template that matches interfaces to their expected subnet by
CIDR instead of a fragile "first private IP" heuristic.

Added an offline pytest suite (terraform/tests/) that checks the
delivery's internal consistency and runs real terraform init/validate
against the actual vkcs provider schema via a project-local filesystem
mirror (provider binary fetched from its GitHub releases, bypassing the
region-blocked HashiCorp registry) - no cloud credentials or API calls
involved. terraform/versions.tf now declares the previously-missing
required_providers block.

Ansible (inventory.ini, base/frr_router/keepalived roles) still assumes
the old 2-router/2-NIC/VRRP topology and is not yet adapted - documented
as a follow-up, not addressed here.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011hXR2ftXZZhJ4Y3XuSoR8r
2026-09-03 16:03:12 +03:00

6.8 KiB
Raw Blame History

Summary: адаптивное количество ВМ-маршрутизаторов и 3 интерфейса

Дата: 2026-09-03 План: 2026-09-03-adaptive-router-vm-count-plan.md

Что сделано

terraform/variables.tf

Добавлены переменные: router_count (default 2, >= 1), private_supernet (default 10.90.0.0/16), private_subnet_prefix_length (default 29, допустимо 28/29), router_availability_zones (default ["ME1"]).

terraform/main.tf

  • Добавлен locals.router_private_subnets — детерминированная непересекающаяся нарезка CIDR из private_supernet на пары (router_index × роль) через cidrsubnet().
  • lan_port1/lan_port2 (фиксированные порты на общей 10.200.10.0/24) заменены на for_each-ресурсы router_priv_net / router_priv_subnet / router_priv_port — по одной изолированной микросети на каждый (роутер, приватная роль).
  • router1/router2 заменены на единый vkcs_compute_instance.router с count = var.router_count: WAN-сеть без изменений + dynamic "network" по 2 приватным портам; user_data теперь рендерится через templatefile().
  • lan_net/lan_subnet, private_sg, priv_srv_01/02/03 не изменялись (отдельный сегмент приватных серверов).
  • Файл прогнан через terraform fmt -recursive (единственные изменения — форматирование существующих строк, семантика не менялась).

terraform/scripts/network-init.sh → terraform/scripts/network-init.sh.tpl

  • Файл переименован (git mv) и превращён в Terraform-шаблон.
  • Все существующие bash brace-expansions (${netmask}, ${partial_octet}, ${octets[@]}) экранированы как $${...}, чтобы Terraform не пытался их интерполировать.
  • WAN-детект (эвристика по первому публичному IP) не изменён.
  • Приватные интерфейсы теперь определяются не эвристикой "первый приватный IP", а сопоставлением по CIDR: Terraform передаёт список private_interfaces (по 2 записи {cidr, name} на роутер), из которого шаблонная директива %{ for pi in private_interfaces } генерирует bash-массив PRIV_TARGETS. Добавлены функции ip_to_int()/ip_in_cidr() для проверки принадлежности IP подсети.
  • netplan-конфиг: секция wan-iface (eth0) без изменений; вместо единственной lan-iface — цикл, генерирующий отдельную ethernets-секцию на каждый найденный приватный интерфейс (eth1, eth2, ...), без default route (изолированные микросети).
  • Проверки/fail-hard/backup/apply/reboot логика сохранена.

terraform/terraform.tfvars

Добавлены закомментированные примеры новых переменных.

README.md

Обновлено описание архитектуры: N роутеров вместо пары, 3 интерфейса на роутер (1 публичный + 2 изолированных приватных, без общего LAN и без VRRP на роутерах), упомянуты новые переменные и то, что network-init.sh стал Terraform-шаблоном. Явно отмечено, что диаграммы (ports.svg, topology.svg) и Ansible-слой (ansible/inventory.ini, роли base/frr_router/keepalived) пока отражают старую схему — это отдельный будущий шаг.

Что осознанно не менялось

  • Ansible-слой — по явному решению в рамках этого изменения. ansible/inventory.ini и роли base/frr_router/keepalived/gre жёстко используют eth0/eth1 и только хосты router1/router2; с новым дизайном (N роутеров, eth1+eth2, без VRRP) они не совместимы и потребуют отдельной переработки перед реальным деплоем через Ansible.
  • priv_srv_01/02/03 и lan_net/lan_subnet — не связаны с роутерами, оставлены как есть.
  • Диаграммы (img/*.svg) — не обновлялись, отражают старую топологию.

Верификация

  • terraform fmt -recursive — чисто (после автоформатирования).
  • terraform init -backend=false — не выполнено: провайдер hashicorp/vkcs недоступен из окружения (нет required_providers в репозитории и нет сети до его источника). Это ограничение окружения, не связанное с данным изменением — в репозитории изначально не было блока required_providers.
  • Синтаксис .tpl: выполнена симуляция рендеринга templatefile() (замена $${ → ${, подстановка тестовых значений вместо %{ for }-блока) + bash -n — прошло без ошибок.
  • Логика ip_to_int()/ip_in_cidr() проверена отдельным bash-тестом на 7 сценариях (/29 и /28, совпадения и несовпадения) — все прошли.
  • terraform plan/apply с реальными VK Cloud credentials не выполнялись — terraform.tfvars содержит placeholder-значения, apply создаёт платные облачные ресурсы; это отдельное действие пользователя.

Известные ограничения / задел на будущее

  • Ansible-слой требует отдельной доработки под 3 интерфейса и N роутеров (см. выше).
  • В репозитории отсутствует required_providers/lock-файл для vkcs — это не связано с текущим изменением, но мешает локальной terraform validate/init.
  • Диаграммы не обновлены под новую топологию.