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
51 lines
6.8 KiB
Markdown
51 lines
6.8 KiB
Markdown
# Summary: адаптивное количество ВМ-маршрутизаторов и 3 интерфейса
|
||
|
||
Дата: 2026-09-03
|
||
План: [2026-09-03-adaptive-router-vm-count-plan.md](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`.
|
||
- Диаграммы не обновлены под новую топологию.
|