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
4.8 KiB
Summary: динамическое количество приватных интерфейсов
Дата: 2026-09-03 План: 2026-09-03-dynamic-private-interface-count-plan.md
Что сделано
terraform/variables.tf
Добавлена переменная private_interface_count (number, default 2, validation >= 1) — количество изолированных приватных интерфейсов на роутер, в дополнение к единственному публичному (WAN).
terraform/main.tf
Единственная точечная правка: locals.private_roles заменён с хардкода ["priv1", "priv2"] на генерируемый список [for i in range(var.private_interface_count) : "priv${i + 1}"]. Все производные ресурсы и блоки (router_private_subnets, router_priv_net/router_priv_subnet/router_priv_port через for_each, dynamic "network" в vkcs_compute_instance.router, генерация списка private_interfaces для templatefile(), имена интерфейсов eth${index(...)+1}) уже были параметризованы через local.private_roles в предыдущем изменении и масштабируются автоматически — их трогать не пришлось.
При private_interface_count = 2 (значение по умолчанию) результат идентичен прежнему поведению — регрессии нет.
terraform/scripts/network-init.sh.tpl
Не менялся. Скрипт уже полностью generic: итерируется по bash-массиву PRIV_TARGETS, сформированному из переданного Terraform списка private_interfaces произвольной длины. Единственный хардкод в скрипте — set-name: eth0 для WAN.
terraform/terraform.tfvars
Добавлен закомментированный пример # private_interface_count = 3 (не активирован, чтобы не перекрывать TF_VAR_private_interface_count).
README.md
- Формулировка про интерфейсы обновлена на "1 публичный +
private_interface_countприватных (по умолчанию 2)". - Добавлен раздел "Horizontal scaling via environment variables" с примером
export TF_VAR_router_count=4/export TF_VAR_private_interface_count=3и объяснением, почему это работает "из коробки" (переменные не переопределены вterraform.tfvars, поэтому действует стандартный приоритет TerraformTF_VAR_*→ default). - Упомянута ёмкость пула CIDR (
private_supernet/16при/29подсетях = 8192 блока).
Обоснование "через переменные окружения" без дополнительного кода
Механизм TF_VAR_<имя_переменной> — встроенная возможность Terraform для любой объявленной variable, отдельного кода/обвязки не требуется. Единственное условие — чтобы значение не было жёстко задано в terraform.tfvars (в этом репозитории для router_count и private_interface_count там только закомментированные примеры, так что TF_VAR_* работает без изменений).
Верификация
terraform fmt -recursive— чисто, без изменений (синтаксис валиден).terraform init/validate— не выполнялись повторно: провайдерvkcsнедоступен из окружения (то же ограничение, что и в прошлом изменении, не связано с этой правкой).- Математика нарезки CIDR проверена вручную:
netnum = router_index × length(private_roles) + role_index— строгая биекция (mixed-radix encoding) без коллизий при любыхrouter_count/private_interface_count, пока общее число блоков не превышает ёмкостьprivate_supernetпри заданномprivate_subnet_prefix_length(дефолт: до 8192 блоков — с большим запасом). network-init.sh.tplне менялся — прошлая офлайн-проверка синтаксиса (bash -nна симулированном рендере) остаётся в силе, логика идентична.