Horizontal scale-out of the deployed group per user request - all other requirements unchanged. terraform apply added only router4 and its 2 private ports (3 added, 0 changed, 0 destroyed); the existing 3 routers were untouched. Deployment summary updated with router4's addresses. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011hXR2ftXZZhJ4Y3XuSoR8r
5.4 KiB
Deployment Summary — VK Cloud PROD (4 роутера)
Дата: 2026-09-07 · Статус: развёрнуто и проверено пользователем · Коммиты: 8886c1b, e7bdc46, +horizontal scale-out до 4 роутеров
Что развёрнуто
flowchart TB
INET(("Internet"))
subgraph R1["router1 · 95.163.209.37"]
R1p1["priv1: 10.90.0.12"]
R1p2["priv2: 10.90.0.21"]
end
subgraph R2["router2 · 95.163.209.99"]
R2p1["priv1: 10.90.0.5"]
R2p2["priv2: 10.90.0.28"]
end
subgraph R3["router3 · 95.163.209.23"]
R3p1["priv1: 10.90.0.13"]
R3p2["priv2: 10.90.0.29"]
end
subgraph R4["router4 · 95.163.208.228"]
R4p1["priv1: 10.90.0.6"]
R4p2["priv2: 10.90.0.22"]
end
INET --- R1
INET --- R2
INET --- R3
INET --- R4
NET1[("priv1 network\n10.90.0.0/28")]
NET2[("priv2 network\n10.90.0.16/28")]
R1p1 --- NET1
R2p1 --- NET1
R3p1 --- NET1
R4p1 --- NET1
R1p2 --- NET2
R2p2 --- NET2
R3p2 --- NET2
R4p2 --- NET2
| ВМ | Публичный IP (WAN) | priv1 (10.90.0.0/28) |
priv2 (10.90.0.16/28) |
|---|---|---|---|
| router1 | 95.163.209.37 | 10.90.0.12 | 10.90.0.21 |
| router2 | 95.163.209.99 | 10.90.0.5 | 10.90.0.28 |
| router3 | 95.163.209.23 | 10.90.0.13 | 10.90.0.29 |
| router4 | 95.163.208.228 | 10.90.0.6 | 10.90.0.22 |
Каждая ВМ — 3 сетевых интерфейса (1 внешний + 2 приватных), flavor STD3-4-4, keypair mcs_ru, образ Ubuntu 24.04. Приватные адреса назначены Neutron IPAM автоматически (без ручного вычисления — см. ниже, почему).
terraform apply (изначальный, 3 роутера): 19 added, 0 changed, 0 destroyed.
terraform apply (горизонтальное масштабирование до 4 роутеров, только router_count = 3 → 4 в terraform.tfvars): 3 added, 0 changed, 0 destroyed — только router4 и его 2 приватных порта, остальные 3 роутера не затронуты.
Задача и её реализация
| Требование | Как реализовано |
|---|---|
| Количество роутеров (изначально 3, масштабировано до 4) | router_count в terraform/terraform.tfvars |
| 3 порта на роутер (1 внешний + 2 приватных) | 1 динамический внешний порт + dynamic "network" по числу private_network_cidrs |
| Каждый приватный порт — в своей подсети | vkcs_networking_network/subnet по for_each на каждый CIDR |
Размер приватной подсети /28 |
private_network_cidrs = ["10.90.0.0/28", "10.90.0.16/28"] |
| Только роутеры (без демо-сегмента) | priv_srv_01/02/03, lan_net, private_sg удалены из main.tf |
| Только Terraform, без Ansible | Ansible-плейбук не запускался (осознанное решение, зафиксировано в памяти) |
Что пришлось исправить по пути (реальные баги, найдены при живом деплое)
provider "vkcs"отсутствовал вовсе —username/password/project_id/regionбыли объявлены, но ни к чему не подключены. Добавлен provider-блок + переменныеauth_url,user_domain_name.- SSH-keypair не существовал под сервисным аккаунтом (Nova keypair'ы — per-user, не per-project). Добавлен
vkcs_compute_keypair, регистрирующий ключ изvar.ssh_public_key. - Коллизия IP на приватных портах — ручной расчёт
fixed_ipконфликтовал со служебным портом VKCS (network:dns), автоматически создаваемым в каждой сети. Убрано ручное вычисление IP — адрес назначает Neutron IPAM (гарантированно без коллизий). image_idна верхнем уровне ресурса ВМ при boot-from-volume — по документации провайдера так делать нельзя: Nova возвращает служебную строку вместо UUID образа, из-за чего Terraform считал это дрейфом и пересоздавал уже созданные ВМ при каждом plan.image_idоставлен только внутриblock_device./29оказался слишком тесным — с учётом служебных портов платформы. Заменено на/28.
Подробности каждого фикса — в docs/changes/2026-09-06-provider-auth-wiring-*.md и docs/changes/2026-09-07-router-only-deployment-*.md.
Верификация
venv/bin/pytest terraform/tests -v→ 56 passed (офлайн, без обращения к облаку).- Реальные
terraform init/plan/applyпротив VK Cloud — успех, подтверждено пользователем вручную после развёртывания.