200 lines
17 KiB
Markdown
200 lines
17 KiB
Markdown
# 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).
|