mvm-s3 is a separate VK Cloud project whose admin pre-created two private networks/subnets with a known IP per router. Unify project-managed (private_network_cidrs, IPAM-assigned) and externally-owned (router_networks, fixed-IP) private interfaces into one local.router_interfaces so both share the existing port/dynamic-network mechanism instead of duplicating it. Switch from implicit *.auto.tfvars loading to explicit -var-file per environment (now two share this terraform/ directory) plus a dedicated Terraform workspace for mvm-s3, so PROD's state and credentials are never touched by mvm-s3 applies. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GHfG9FgpMrGdrvC1QUewTw
7.6 KiB
Summary: внешние сети с фиксированными IP для окружения mvm-s3
План: 2026-09-09-mvm-s3-external-networks-plan.md
Что сделано
terraform/variables.tf
private_network_cidrsстала опциональной (default = []), убрана валидация «минимум 1 CIDR» — деплой, использующий толькоrouter_networks(какmvm-s3), не обязан её задавать.- Добавлена
router_networks(map(object({network_id, subnet_id, cidr, ip_addresses})),default = {}) — заранее существующие сети (обычно в другом VK Cloud проекте, только по UUID), в которые каждый роутер получает интерфейс с заранее известным IP. Валидации: корректный CIDR, корректные IPv4-адреса, каждый адрес — внутри своего CIDR.
terraform/main.tf
- Оба механизма (project-managed сети по
private_network_cidrsи внешние поrouter_networks) объединены в одинlocal.router_interfaces(роль →{network_id, subnet_id, cidr, fixed_ips}) — переиспользован существующий паттерн (setproduct, одинvkcs_networking_port, одинdynamic "network") вместо дублирования ресурсов. vkcs_networking_port.router_priv_portпереименован вrouter_iface_port,fixed_ip.ip_addressтеперь условный:nullдля project-managed ролей (как раньше — IPAM сам назначает, избегая коллизии с служебным портомnetwork:dns), явный статический адрес — для ролей изrouter_networks.- Добавлен
lifecycle.preconditionна порт: понятная ошибка, еслиrouter_networks[role].ip_addressesкорочеvar.router_count. network-init.sh.tplне изменялся — он уже сопоставляет интерфейсы по вхождению живого IP в ожидаемый CIDR, независимо от роли и способа назначения адреса.
Окружение mvm-s3 (файлы)
terraform/mvm-s3.tfvars(коммитится) —router_count = 4,private_network_cidrs = [],router_networksс двумя ролями (primary=172.16.252.8/29,backup=172.16.252.0/29) и точными IP на роутер из диаграммы пользователя.ssh_key_nameоставлен плейсхолдером — пользователь должен вписать реальное значение.terraform/mvm-s3.secrets.tfvars.example(коммитится) — шаблон реальных credentials дляmvm-s3.terraform/prod.secrets.tfvars.example(коммитится, заменилprod.auto.tfvars.example) — тот же шаблон для PROD по новой конвенции именования..gitignore— добавлен паттерн*.secrets.tfvars(и.json), старый*.auto.tfvarsоставлен как safety net.
Схема окружений
Поскольку теперь в одном каталоге terraform/ живут 2 окружения с разными credentials/router_count/сетями, отказались от неявной авто-загрузки *.auto.tfvars в пользу явных -var-file + отдельных Terraform workspace на окружение (terraform workspace new mvm-s3). PROD продолжает работать в workspace default со своим state — mvm-s3 их не затрагивает.
Важно (ручной шаг для пользователя, не сделан мной): переименовать существующий terraform/prod.auto.tfvars (реальные PROD-креды) в terraform/prod.secrets.tfvars — я не трогал этот файл, так как он содержит настоящие секреты.
Документация
docs/changes/2026-09-09-mvm-s3-external-networks-plan.md— план (копия согласованного).README.md— новый раздел "External fixed-IP networks and multi-environment workspaces", обновлены упоминания*.auto.tfvars→*.secrets.tfvars, описание тестов.docs/QUICKSTART.md— новый шаг 4а (деплойmvm-s3), обновлён шаг 2 (credentials) и шаг 4 (явные-var-file, workspace).
Тесты (terraform/tests/test_terraform_delivery.py)
73 теста (было 56 по данным DEPLOYMENT_SUMMARY.md, часть добавлена и в предыдущих изменениях), все зелёные. Ключевые добавления/правки:
test_router_networks_variable,test_router_networks_validation_is_enforced(валидный/невалидный CIDR, IP вне подсети, дефолтный{}).test_private_network_cidrs_variable/test_private_network_cidrs_validation_is_enforcedобновлены под новыйdefault = [].test_router_interfaces_local_merges_both_network_sources,test_router_interface_roles_local_is_keys_of_router_interfaces,test_router_network_blocks_scale_with_router_interface_roles— заменили тесты на удалённыйlocal.private_roles.test_router_iface_port_ip_address_is_conditional_on_fixed_ips,test_router_iface_port_has_length_precondition_for_fixed_ips— заменили тест на переименованныйrouter_priv_port.test_mvm_s3_tfvars_*— сверяютmvm-s3.tfvarsс диаграммой (UUID, CIDR, IP), запрет project-managed сетей, покрытиеrouter_countчислом IP.test_secrets_tfvars_example_is_not_gitignored,test_gitignore_excludes_secrets_tfvars_overlay,test_committed_tfvars_have_no_auth_credentials— заменили тесты на удалённыйprod.auto.tfvars.example.test_terraform_init_and_validate_against_real_provider_schema— добавленmvm-s3-образный кейс (private_network_cidrs=[]+ 2 ролиrouter_networks) для проверки схемы реального провайдера.
Прогон: venv/bin/terraform fmt -check — чисто; venv/bin/pytest terraform/tests -v — 73 passed.
Что НЕ сделано (осознанно, вне зоны моего доступа)
terraform plan/applyв проектеmvm-s3— у меня нет доступа к этому VK Cloud проекту; должен выполнить пользователь (команды — вdocs/QUICKSTART.md§4а).- Переименование реального
terraform/prod.auto.tfvars→prod.secrets.tfvars— файл содержит настоящие секреты, переименовать должен пользователь сам. - Заполнение реальных credentials/
ssh_key_nameдляmvm-s3— плейсхолдеры оставлены намеренно, я не должен их придумывать. - Проверка актуальности
sdn = "sprut"на порту в чужую сеть — отмечено вmain.tfкомментарием, требует подтверждения на первом реальномplan/apply.