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

200 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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).