Files
tf_provider/docs/CHAT_RESUME_IAC_2026-09-24.md
T
2026-09-24 07:25:27 +03:00

17 KiB
Raw Blame History

CHAT RESUME: IaC-развёртывание Штурвала — состояние на 2026-09-24

Кому: новый чат / новый участник. Читать целиком, это хендовер. Что это: сводка длинной сессии (2026-09-23/24) по вопросу «как дать клиенту IaC для цепочки Штурвал». Статус: решение НЕ принято, код НЕ написан. Есть анализ, проверенные факты и развилка.


0. TL;DR (одним абзацем)

Клиенту нужен настоящий IaC: один конфиг + terraform apply = вся инфраструктура. Цепочка Штурвала (vcOrg → vcVdc → vcNsxt → [modify оргов/эдж] → k8sShturval) упирается в две операции modify, которые провайдер сейчас выразить не может: в схеме tf-ресурса их параметров нет (схема строится только из create). Ручной ЛК и скрипт отклонены — это не IaC. Единственный каноничный путь — отдельные tf-ресурсы под модификации (как сделано в провайдере VMware Cloud Director, прецедент в папке !/), плюс желательно, чтобы платформа отдавала через API выводимые значения (ipSpaceName), которые юзер знать не может. Часть прежних «блокеров» оказалась ложной — см. §7, это критично.


1. Задача

Развернуть Штурвал (k8s) целиком через Terraform, с корректным apply/plan/destroy:

vcOrg    -> create       (в нашем случае орг уже создана вручную и НЕ в state)
vcVdc    -> create
vcNsxt   -> create       (Edge)
------------------------------
vcOrg    -> modify       (аллокация внешних IP: vIPConfigure)
vcNsxt   -> modify       (включить SNAT, указать внешний IP из vcOrg: ipSpaceName)
------------------------------
k8sShturval -> create

Операции строго последовательны. Проблема: между nsxt.create и shturval.create стоят два modify, которые в один tf-ресурс не укладываются.


2. Позиции участников (Telegram 2026-09-23)

Кто Позиция
Владимир (наш) Пытается сделать всё терраформом. create — ок, modify — «просто так не получится, надо создавать дополнительные ресурсы-модификаторы». Сомневался: может, руками в ЛК или скриптом.
Георгий Основной запрос клиента — IaC. Ручной ЛК/скрипт «совсем не подойдёт». Правильно указал порядок: сначала nsxt, потом квота на оргу.
Дмитрий Хочет «terraform apply одного ямлика со всей инфрой — и всё». Спрашивал, как это реализовано в провайдере Cloud Director из провайдерской УЗ.
Виталий Дал 3 tf-файла (vmware_org.tf, vdc.tf, network.tf.tmpl) — официальный провайдер Cloud Director. Ключевое: ipSpace → providerGateway → providerVdc (цепочка, которую юзер не знает), «квоту делаем через API на оргу, т.к. эджей много, а орга одна», «при создании параметры подкладываются», «в организации один T0».

3. Подтверждённые факты (с источниками)

  1. Схема tf-ресурса строится ТОЛЬКО из create (генератор TOOLS/resource-generator). → modify-only параметры в схему не попадают.
  2. vIPConfigure (vc_org, modify id 207, param id 662, array-map-fixed, sub: name=39, count=40) есть только в modify. В create (id 136) — только resourceRealm(418), organizationType(556), orgSuffix(1125). Файл: generated/dev/resources_yaml/19_vc_org.yaml.
  3. ipSpaceName (vc_nsxt, modify id 111, param id 372, string, required false) есть только в modify. В create (id 10) — vdcUid, needEnableAVI(340), virtualServicesCount(341), qosProfile(825), routedNetConfiguration(1110). Файл: generated/dev/resources_yaml/22_vc_nsxt.yaml.
  4. vIPConfigure — replace-семантика, НЕ накопительная. Повторный modify с тем же count не задваивает (1→1), работает вверх/вниз/до 0, count=0 принимается (несмотря на minvalue:1), live читается из state.params. Источник: docs/ORG_IP_MODIFIER_TEST_2026-09-22.md (проверено на стенде DEV_STAND/FullPipe, провайдер 2.0.9).
  5. ipSpaceName — выводимое значение: цепочка providerVdc → providerGateway → ipSpace, юзер его не знает. Платформа сейчас «подкладывает» недостающие параметры при создании пустой орги. Список доступных ipSpace в статической выгрузке (/instanceOperations/default/{id}) — пустой, виден только в ЛК/живом инстансе. (Виталий + форензика)
  6. Допущение платформы: в организации один T0/провайдер-шлюз. Рост T0 отложен, но при нём схема сломается.
  7. Доступ к значению modify-параметра: live берётся из GET /instances/{uid} → state.params, а НЕ из cfsParams.paramValue (это сохранённый дефолт формы от прошлых прогонов, см. dtCreated в HAR).
  8. Flow modify (HAR org_enough_.har): POST /instanceOperations {instanceUid, operation:"modify"} → POST /instanceOperationCfsParams {paramValue, instanceOperationUid, svcOperationCfsParamId} → POST /instanceOperations/{opUid}/validate-cfs → POST /instanceOperations/{opUid}/run.
  9. Прецедент (VCD, папка !/): та же цепочка делается отдельными ресурсами с depends_on: vcd_nsxt_alb_settings (count = var.alb_enable ? 1 : 0), vcd_nsxt_alb_edgegateway_service_engine_group (reserved_virtual_services), vcd_network_routed_v2, vcd_ip_space_custom_quota (на оргу). Приём «включено/выключено» = существование ресурса; inverse = удаление ресурса.
  10. Nubes — надстройка над Cloud Director. Наши vcOrg/vcVdc/vcNsxt создают объекты в VCD. Провайдер Nubes — обёртка над API Nubes, отдельный от официального terraform-provider-vcd.

4. Почему «просто добавить поле» / «насильно в state» / «скрипт» — не работает

  • Добавить поле в .tf → падает на plan: атрибута нет в схеме (см. §3.1).
  • Terraform не может внутри одного ресурса сделать «create → через N шагов modify». Декларативный Update требует желаемого состояния; ipSpaceName — это включение SNAT, а не значение поля.
  • Вписать в tfstate нельзя: state валидируется по схеме провайдера, а «записанное» состояние ≠ реальность (получишь чистый plan при сломанной инфраструктуре). null_resource/terraform_data + local-exec даёт только факт выполнения, не состояние.
  • Ручной ЛК / скрипт вне tf — отклонено: это не IaC (нет версионирования, воспроизводимости, дрейфа, отката).
  • Правка провайдера «по-старому» (метки kind: modifier в YAML + реестр в yaml-generator) — отменённый заход, см. §7.

5. Каноничное решение (что делать)

Два независимых требования — нужны оба:

  1. Отдельные tf-ресурсы под modify (наша сторона): e.g. nubes_org_ip_allocation (vIPConfigure), nubes_nsxt_network (needEnableAVI/virtualServicesCount/ipSpaceName/routedNetConfiguration), привязка через depends_on к орге/эджу.
    • Read = читать родителя (state.params), Delete = обратный modify (count=0 / needEnableAVI=false / ipSpaceName="no-needed"), Create/Update = modify с параметрами.
  2. Доступ к выводимым значениям через API (сторона платформы): динамические valueList + цепочка providerVdc → providerGateway → ipSpace. Иначе юзер подсматривает в ЛК (ручной ввод как временный долг допустим, но поле надо делать Optional+Computed, чтобы позже включить автоподстановку без breaking change).

Дизайн-требования, заложить сразу:

  • ip_space_name → Optional + Computed;
  • optional селектор шлюза (t0_id / provider_gateway) — чтобы рост T0 не сломал схему;
  • не тащить доменные метки в универсальный YAML (см. §7).

6. Что можно делать уже сейчас, не дожидаясь платформы

  • vIPConfigure (аллокация IP на оргу) — можно делать начисто: блокеров нет, replace-семантика подтверждена тестом, Read/Delete выражаются через state.params и count=0.
  • needEnableAVI / virtualServicesCount — выразимы (есть и в create, и в modify).
  • ipSpaceName — единственное, что упирается в платформу; временно — ввод юзером (значение он и так смотрит в ЛК).
  • routedNetConfiguration — есть в create (1110) и modify (1112), выразимо.

Не решено (требует решения до кода):

  • откуда генератор берёт список доменных ресурсов (это не данные API, а доменное знание — то самое место, где раньше был реестр в yaml-generator). Форму выбрать осознанно: явный список vs отдельный вход.
  • какие шаги вообще остаются на провайдерском (облачном) уровне, а какие отдаются тенанту (квота ipSpace / ALB — возможно, это уровень облака, и тогда в клиентский tf они не входят).

7. ⚠️ Исправленные ошибки (НЕ повторять!)

  1. Ложный факт «vIPConfigure накопительный». Был протащен в промпт для Opus как «подтверждённый», из-за чего Opus построил вывод «накопительный API несовместим с декларативной моделью» и объявил два «блокера» (Read счётчика, адресное освобождение). Оба ложны — тест ORG_IP_MODIFIER_TEST_2026-09-22.md доказывает идемпотентность и работу в обе стороны. Документы исправлены.
  2. Прежняя repo-память (modifier-gotchas.md) содержала устаревшие утверждения (эпоха 09-21/22): kind: modifier, delete_strategy, nubes_vc_nsxt_network, «у vc_nsxt нет instance-modify», «Update = no-op». Файл перезаписан актуальными фактами. НЕ использовать старую формулировку.
  3. Старые «модификаторы» были написаны и даже работали (09-22), но заход признан негодным: доменную логику вшили в универсальный генератор (метки в YAML). Соответствующие документы помечены баннером LEGACY.

8. Карта файлов

АКТУАЛЬНО (источник истины):

  • docs/CHAT_RESUME_IAC_2026-09-24.md ← этот файл
  • docs/SHTURVAL_IAC_MODIFY_ANALYSIS_2026-09-23.md — анализ, варианты A–E, мнение
  • docs/OPUS_ANSWER_IAC_SHTURVAL_MODIFY_2026-09-23.md — ответ Opus + поправки (ложные блокеры сняты)
  • docs/ORG_IP_MODIFIER_TEST_2026-09-22.md — проверенные факты по vIPConfigure
  • docs/prompts/prompt_for_opus_iac_shturval_modify.md — промпт (факты исправлены)
  • generated/dev/resources_yaml/19_vc_org.yaml, 22_vc_nsxt.yaml — спеки (факты по операциям/параметрам)
  • HAR/org_enough_.har, HAR/org2.har, HAR/edge_.har — live-семантика modify
  • !/ — прецедент Cloud Director (3 файла vcd_*), НЕ наш код

LEGACY (история, НЕ источник истины):

  • PLAN_modifier_redesign.md ⛔ (баннер добавлен)
  • docs/60_strategy/modifier_resources_ideology_and_specification.md ⛔ (баннер добавлен)
  • docs/inverse_rollback_analysis_2026-09-23.md
  • prompt_for_opus_modifier_global_architecture.md, prompt_for_opus_modifier_review_2.md (корень)
  • docs/prompts/prompt_for_opus_modifier_*.md, docs/prompts/prompt_for_opus_modifiable_architecture.md
  • HISTORY/OPUS/2026-09-22_modifier_*.md
  • PLAN_regenerate_providers_0.0.1.md — перекрыт PLAN_FLASH_reversion_cleanup.md (0.0.1 объявлен легаси)

Примечание: docs/ORG_IP_MODIFIER_TEST_2026-09-22.md — актуален (это отчёт по проверке, не план).

Инфра-контекст:

  • TOOLS/config/<стенд>/profile.env → NUBES_API_ENDPOINT, TOKEN_FILE
  • VERSIONS.md — залитые версии (DEV на 09-22 = 2.0.13; в generated/dev/provider_build/ лежат 2.0.17 — расхождение)

9. Развилка (ждёт решения)

Вариант Суть Вердикт
A Отдельные tf-ресурсы под modify (+ позже data-source для ipSpace) канон; реализуемо сейчас для vIPConfigure
B То же, но значения вводит юзер вручную приемлемый временный долг при Optional+Computed
C Ждать новых спеков платформы часть работ всё равно можно начать сейчас
D Ручной ЛК / скрипт вне tf ❌ отклонено (требование IaC)
E Пресеты/дефолтное окружение снижает боль на старте, IaC не заменяет

Не принято: делать ли modify-ресурсы доменными «руками» (и как их перечислять в генераторе) — вопрос архитектуры; и что из шагов остаётся за облаком.


10. Открытые вопросы к людям

  1. Георгию/продукту: какие шаги цепочки — тенантские, а какие — уровень облака (квота ipSpace, ALB)? От этого зависит объём ресурсов в клиентском tf.
  2. Виталию (платформа): можете отдавать через API (а) динамические списки значений (ipSpace), (б) цепочку providerVdc → providerGateway → ipSpace?
  3. Виталию: файлы !/ — ваш инструмент провижининга от провайдерской УЗ или справочный пример? (в диалоге он сказал только «это провайдер от клауд директора»)
  4. Команде: откуда генератор берёт список доменных ресурсов-модификаций (форма решения, без меток в YAML).