private_supernet/private_subnet_prefix_length/private_interface_count
(which auto-derived per-router-per-role micro-subnets via cidrsubnet())
are replaced by a single required variable, private_network_cidrs: one
CIDR per shared private network that router VMs get an interface into,
supplied explicitly by the admin - no auto-carving. Each router gets its
own port/IP inside every listed network (cidrhost(cidr, router_index+2)),
closer to the original lan_net design but generalized to N networks and
N routers. network-init.sh.tpl needed no changes - it already matches
interfaces by CIDR membership regardless of whether the CIDR is shared.
Also fixes a testing gap found along the way: `terraform validate` does
not enforce variable validation{} blocks for externally-supplied values
in this terraform version - only `plan`/`apply` do. The test suite now
exercises those validations for real via `terraform plan` against an
isolated, provider-free copy of variables.tf.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011hXR2ftXZZhJ4Y3XuSoR8r
5.9 KiB
Summary: явная передача префиксов приватных сетей
Дата: 2026-09-03 План: 2026-09-03-explicit-private-network-cidrs-plan.md
Что сделано
terraform/variables.tf
Удалены private_supernet, private_subnet_prefix_length, private_interface_count. Добавлена обязательная (без default) переменная private_network_cidrs (list(string)) с тремя validation-блоками: список не пуст, каждый элемент — валидный IPv4 CIDR (can(cidrhost(c, 0))), элементы уникальны.
terraform/main.tf
Модель изменена: вместо N×router_count изолированных микроподсетей (по одной на каждую пару "роутер+роль", auto-carved через cidrsubnet()) — N общих приватных сетей, по одной на каждый CIDR из private_network_cidrs. router_priv_net/router_priv_subnet теперь for_each только по ролям (local.private_network_cidr, карта role→CIDR); router_priv_port — for_each по (роутер×роль), с fixed_ip = cidrhost(role_cidr, router_index + 2) (.2=router1, .3=router2, ...). templatefile() берёт CIDR напрямую из local.private_network_cidr[role].
terraform/scripts/network-init.sh.tpl
Не менялся — сопоставление интерфейсов по CIDR-принадлежности не зависит от того, общий CIDR или уникальный per-роутер.
terraform.tfvars
Заменены закомментированные private_supernet/private_subnet_prefix_length/private_interface_count на рабочий (не закомментированный, т.к. обязательный) пример:
private_network_cidrs = [
"10.90.0.0/29",
"10.90.0.8/29",
]
terraform/tests/test_terraform_delivery.py
Существенно переработан (32 теста вместо 32 — состав изменился):
- убраны carving-коллизии (
cidrsubnet-реимплементация) — авто-нарезки больше нет; - добавлен
test_tfvars_private_network_cidrs_do_not_overlap_and_have_room_for_routers— офлайн-проверка (ipaddress) примера изterraform.tfvars: без пересечений, вмещаетrouter_count + 2адресов; - добавлены
test_private_network_cidrs_validation_is_enforcedиtest_router_count_validation_is_enforced— реальная проверка срабатыванияvalidation-блоков черезterraform planна изолированной копии одногоvariables.tf(без провайдера, без обращений к облаку); - параметризованный
test_terraform_init_and_validate_against_real_provider_schemaобновлён подprivate_network_cidrs(JSON-список черезTF_VAR_*).
README.md / docs/QUICKSTART.md
Убрано описание авто-нарезки и "8192 блоков" (в README также устранён случайно задвоенный абзац из предыдущего шага). Добавлено описание новой модели (общие сети, явные префиксы) и актуальный пример TF_VAR_private_network_cidrs.
Важная находка в процессе
terraform validate не проверяет пользовательские validation { ... }-блоки переменных для значений, заданных извне (-var/TF_VAR_*/tfvars) — эмпирически подтверждено на минимальном изолированном примере (без единого resource/provider) с этим бинарём Terraform (v1.16.1): validate даёт Success! даже для заведомо невалидных значений (router_count=0, дублирующиеся CIDR, пустой список, некорректный CIDR-синтаксис), тогда как terraform plan с теми же значениями корректно завершается ошибкой Invalid value for variable. Это касается не только новой переменной, но и ранее написанной router_count >= 1.
Из-за этого предыдущий вывод (в summary от 2026-09-03 про GitHub-зеркало провайдера) о том, что "реальный terraform validate подтверждает корректность конфигурации" был верен только в части совместимости со схемой провайдера — но не проверял ничего про custom variable validation. Это исправлено: теперь validation-блоки проверяются через terraform plan на изолированной копии variables.tf (без провайдера, без облака) — см. новые тесты выше.
Верификация
venv/bin/terraform fmt -check -recursive→ чисто.- Реальные
terraform init/validate(через локальный filesystem-mirror провайдера) на 3 сочетанияхrouter_count/private_network_cidrs, включая дефолт изterraform.tfvars→ все успешны. - Реальный
terraform planна изолированномvariables.tf— 4 негативных/позитивных сценария дляprivate_network_cidrsи 3 дляrouter_count→ validation срабатывает корректно в обе стороны. venv/bin/pytest terraform/tests -v→ 32 passed.