docs(history): раскладка HISTORY по тематическим папкам (75 файлов)
Было: 41 файл в корне HISTORY/ + авторские папки OPUS/ и SONNET/ (34 файла). Стало — тематическая нумерация в стиле NOTES/ (10_, 20_, …): 10_reviews/ ревью кода и разборы от LLM (2) 20_releases/ заливки версий в реестр, чистки реестра, нумерация версий (8) 30_provider/ ядро провайдера: архитектура, модификаторы, UUID, nested (6) 40_generator/ генератор YAML/спеки, формат MAN (3) 50_docs/ пайплайн документации, навигация, публикация, хостинг S3 (9) 60_stands/ стенды и примеры: CRUD, FullPipe, Штурвал, TEST_STAND (7) 70_infra/ реестр, API Gateway, DDoS-Guard, VPN/213, зеркала (4) 90_llm/ диалоги и промпты с LLM вне тематики: OPUS/, SONNET/, gemini/ (34) OPUS/ и SONNET/ перенесены как есть в 90_llm/ — чтобы не рвать пары «бриф → ответ» внутри диалогов. Все переносы — через git mv (история сохранена). Перед правкой: TMP/backup_2026-10-02/HISTORY_before_restructure.tar.gz. Перекрёстные ссылки обновляются следующим коммитом.
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
# 2026-07-21 — CRUD-стенд: три приложения + PG
|
||||
|
||||
## Сделано
|
||||
|
||||
### Провайдер
|
||||
- TEST 5.1.16, DEV 3.1.13 — fix: modify only if `hasServiceParamChanges` (не дёргает API при смене только git_revision)
|
||||
- Шаблон — sequential modify→redeploy вместо if-else
|
||||
|
||||
### TEST_STAND/CRUD — рефакторинг
|
||||
- `LUCEE/` → `CRUD/` (папка переименована)
|
||||
- `nubes_postgres.npg_lucee` → `nubes_postgres.main_pg`
|
||||
- Файлы: `nubes_postgres_lucee.tf` → `postgres.tf`, `userUNDdb.tf` → `postgres_user_db.tf`
|
||||
- Добавлены: `flask.tf`, `nodejs.tf`
|
||||
- `locals.tf` — каждая строка с комментарием
|
||||
- `terraform.tfvars.example` — только нужные поля с пояснениями
|
||||
- `README.md` — для нового пользователя (где брать токен, как запускать)
|
||||
|
||||
### DEV_STAND/CRUD — аналог TEST
|
||||
- Те же файлы, провайдер `nubes-dev`, версия `3.1.13`
|
||||
- `locals.tf` — каждая строка с комментарием
|
||||
- `terraform.tfvars.example` — только нужные поля
|
||||
|
||||
### Приложения (три репо)
|
||||
|
||||
| Репо | Хеш | Что |
|
||||
|---|---|---|
|
||||
| `tfluceecrud` | `8268568` | Убран `DROP TABLE` → `CREATE TABLE IF NOT EXISTS` |
|
||||
| `tfflaskcrud` | `54746e9` | `init_db()` на уровне модуля (gunicorn) |
|
||||
| `tfnodejscrud` | `809d30b` | `app.listen` вне `initDB.then()`, SSL в Pool |
|
||||
|
||||
Все три — идентичный SQL, одна таблица `crud_items`, Nubes design.
|
||||
|
||||
### Баги исправлены
|
||||
1. **Lucee DROP TABLE** — при каждом старте приложения таблица дропалась, данные терялись
|
||||
2. **Flask init_db** — только в `__main__`, под gunicorn таблица не создавалась
|
||||
3. **Node.js startup** — `app.listen` внутри `.then()` — если PG не ответил, сервер не стартовал. Исправлено: `app.listen` вынесен наружу, `initDB` с `.catch()`
|
||||
4. **Node.js PGSSLMODE** — не передавался в `json_env` (только Lucee/Flask). PG требовал SSL → `pg_hba.conf rejects connection ... no encryption`
|
||||
5. **Flask sslmode** — пытались добавить в `psycopg2.connect()`, но Flask работал и без него (PG в том же кластере). Откачено.
|
||||
6. **s3_name в документации** — исправлено «S3 → Пользователи» → «S3 → Имя экземпляра»
|
||||
7. **Домены в комментариях** — везде `.dev.nubes.ru`, убрано ошибочное `.test.nubes.ru`
|
||||
|
||||
### tf_examples — репозиторий примеров
|
||||
- Создан `https://gitea.services.ngcloud.ru/Nail/tf_examples.git`
|
||||
- `CRUD/` — копия `TEST_STAND/CRUD/`, без токенов (`.gitignore *.tfvars`)
|
||||
- `SHTURVAL_MGMT/` — management-кластер Штурвал (сервис 148), подробный README
|
||||
- Корневой README с перечнем примеров
|
||||
|
||||
### Импорт инстансов в Terraform
|
||||
- `terraform import nubes_<тип>.<имя> <instance-uid>`
|
||||
- UUID из URL: `deck-.../services/instance/detail/<uuid>`
|
||||
- Импорт работает, но **Read падает с 404 если инстанс создан другим пользователем** — API возвращает 403/404
|
||||
- Чужие инстансы импортировать нельзя
|
||||
|
||||
### README во всех репо
|
||||
- Три репо приложений — одна строка: «Деплоится через Terraform (nubes_...)»
|
||||
- Убраны `npm install`, `pip install`, `gunicorn` — всё делает платформа
|
||||
|
||||
### Известное ограничение
|
||||
PG+user+DB и приложения нельзя создать за один apply — `vault_secrets["users"]` не заполнен на момент создания приложений. Два apply. Подробнее в README.
|
||||
|
||||
## Важные выводы
|
||||
- **Не менять код без «делай»** — нарушал неоднократно (Flask sslmode, try() в tf)
|
||||
- **Проверять YAML перед созданием кода** — структура папок (Flask `site/`, Node.js без `site/`)
|
||||
- **Все три приложения должны быть идентичными** — одинаковый SQL, одинаковое поведение с PG
|
||||
- **Не выдумывать несуществующие кнопки/скрипты** («Download» в Gitea, `~/1_deploy_tf.sh`)
|
||||
@@ -0,0 +1,73 @@
|
||||
# Настройка Terraform для разных стендов
|
||||
|
||||
Дата: 2026-08-31
|
||||
|
||||
## Матрица стендов
|
||||
|
||||
| Стенд | Рабочие каталоги | Provider source | API endpoint | Версия в найденных Terraform-файлах |
|
||||
|---|---|---|---|---|
|
||||
| DEV | `DEV_STAND/CRUD`, `DEV_STAND/POSTGRES`, `DEV_STAND/IOT_KAFKA_DEMO`, `DEV_STAND/SHTURVAL_MGMT` | `tf-registry.containerk8s.services.ngcloud.ru/nubes-dev/nubes` | `https://lk-api-gateway-dev.ngcloud.ru/api/v1/svc` | обычно `3.x` |
|
||||
| TEST | `TEST_STAND/CRUD`, `TEST_STAND/PG`, `TEST_STAND/POSTGRES`, `TEST_STAND/MARIA_DB`, `TEST_STAND/IOT_RMQ_DEMO`, `TEST_STAND/buck0`, `TEST_STAND/kuber` | `tf-registry.containerk8s.services.ngcloud.ru/nubes-test/nubes` | `https://lk-api-gateway-test.ngcloud.ru/api/v1/svc` | обычно `5.x` |
|
||||
| PROD | `PROD_STAND/PG1`, `PROD_STAND/POSTGRES`, `PROD_STAND/RABBIT` | `tf-registry.containerk8s.services.ngcloud.ru/nubes/nubes` | `https://lk-api-gateway.ngcloud.ru/api/v1/svc` | обычно `2.x` |
|
||||
|
||||
Provider выбирается в `terraform { required_providers { nubes { ... } } }` конкретного рабочего каталога. API endpoint задаётся в блоке `provider "nubes"`.
|
||||
|
||||
## Что настраивать
|
||||
|
||||
1. Перейти в конкретный каталог конфигурации, например `TEST_STAND/PG`.
|
||||
2. Создать локальный файл `terraform.tfvars` по шаблону `terraform.tfvars.example`, если он есть.
|
||||
3. Заполнить только переменные, объявленные в `main.tf`/`variables.tf`:
|
||||
- `api_token` — токен того же стенда;
|
||||
- `realm` — Kubernetes-платформа/кластер;
|
||||
- `s3_uid` или `s3_user_uid` — UUID S3 для backup или ресурса bucket;
|
||||
- `s3_name` — имя S3, если это предусмотрено конфигурацией;
|
||||
- дополнительные `org_uid`, `vdc_uid`, `edge_uid`, `sizing_policy` — только для соответствующих ресурсов.
|
||||
4. Проверить имена ресурсов и параметры в остальных `.tf`-файлах: `resource_name`, домены, `git_revision`, CPU, memory, replicas, disk, PostgreSQL version, backup schedule и `adopt_existing_on_create`.
|
||||
5. Выполнить Terraform из этого же каталога:
|
||||
|
||||
```bash
|
||||
terraform init
|
||||
terraform plan
|
||||
terraform apply
|
||||
```
|
||||
|
||||
Для CRUD-конфигураций с PostgreSQL сначала требуется первый `terraform apply` для базы, пользователя и БД, затем второй `terraform apply` для приложений. Это прямо указано в `TEST_STAND/CRUD/README.md`.
|
||||
|
||||
## Передача токена
|
||||
|
||||
Токен не следует хранить в репозитории. Допустимые варианты:
|
||||
|
||||
```bash
|
||||
export TF_VAR_api_token="..."
|
||||
terraform plan
|
||||
```
|
||||
|
||||
или локальный `terraform.tfvars`, исключённый из публикации. Не использовать PROD-токен в DEV/TEST и не использовать TEST-токен в PROD.
|
||||
|
||||
## State и backend
|
||||
|
||||
В проверенных стендах нет блока `backend` и отдельных backend-конфигураций. Если backend не добавлен локально, Terraform использует локальный state в рабочем каталоге (`terraform.tfstate`). Нельзя запускать два разных стенда с одним state; для общего или удалённого state нужен отдельный backend с уникальным bucket/key для каждого стенда.
|
||||
|
||||
## Профили сборки provider
|
||||
|
||||
`TOOLS/config/{dev,test,prod}/profile.env` используется скриптами сборки и публикации provider, а не Terraform-манифестами стендов:
|
||||
|
||||
| Профиль | API | Token file | Namespace | Версия профиля |
|
||||
|---|---|---|---|---|
|
||||
| `dev` | dev Gateway | `secrets/dev.token` | `nubes-dev` | `3.0.7` |
|
||||
| `test` | test Gateway | `secrets/test.token` | `nubes-test` | `5.0.6` |
|
||||
| `prod` | production Gateway | `secrets/prod.token` | `nubes` | `2.0.7` |
|
||||
|
||||
Для сборки использовать профильный pipeline из `HOWTO-UPLOAD.md`, а не смешивать профиль одного стенда с Terraform-конфигурацией другого.
|
||||
|
||||
## Найденные расхождения и риски
|
||||
|
||||
- `docs/ops/STANDS.md` содержит устаревшие `deck-api-*`, старые пути `devops/profiles` и версии, не совпадающие с `TOOLS/config/*/profile.env` и частью Terraform-файлов.
|
||||
- Версии provider неоднородны даже внутри одного стенда: перед запуском нужно сверять `required_providers` конкретного каталога с опубликованной версией.
|
||||
- В `PROD_STAND/PG1/terraform.tfvars` обнаружен токен в открытом виде. Его нужно отозвать/заменить в Nubes и удалить из локального файла перед публикацией или передачей репозитория.
|
||||
- В отдельных PROD-файлах встречаются захардкоженные пароли и адреса внешних сервисов; их следует перенести в переменные/секретное хранилище перед использованием в общем доступе.
|
||||
- `TEST_STAND/PG/README.md` указывает версии и структуры параметров, которые могут отличаться от текущего `main.tf`; источником истины для запуска считать сам каталог Terraform и lock-файл после `terraform init`.
|
||||
|
||||
## Синхронизация на VM
|
||||
|
||||
`DEV_STAND/sync.sh` и `TEST_STAND/sync.sh` синхронизируют конфигурацию на VM и исключают `.terraform`, state и lock-файл. Перед синхронизацией проверить целевой стенд и не переносить state между стендами.
|
||||
@@ -0,0 +1,62 @@
|
||||
# 2026-09-24 — Штурвал dev-00: диагностика, adopt и дизайн «freeze on destroy»
|
||||
|
||||
Краткая запись по дню. Разбор с источниками (файл:строка, ответы API, логи) —
|
||||
`NOTES/30_analysis/SHTURVAL_DEV00_DIAG_AND_FREEZE_DESIGN_2026-09-24.md`,
|
||||
резюме для продолжения — `NOTES/40_chat_summaries/CHAT_RESUME_2026-09-24_shturval_freeze.md`.
|
||||
|
||||
## Изменения в репозитории
|
||||
|
||||
| Что | Файл | Коммит |
|
||||
|---|---|---|
|
||||
| `adopt_existing_on_create = true` для кластера Штурвала (иначе apply падал на существующем suspended-инстансе) | `DEV_STAND/FullPipe/shturval.tf` | `57abb7b` |
|
||||
| Документация сессии (диагностика + дизайн freeze) | `NOTES/30_analysis/…`, `NOTES/40_chat_summaries/…` | `3df93ad` |
|
||||
| Универсальный третий режим destroy `keep_on_destroy` (`state_only`) для всех instance-ресурсов + предупреждения в `Delete` | `TOOLS/resource-generator/{types.go,loader.go,templates/instance.go}` | `22c6c83` |
|
||||
| Режим «заморозки» в конфиге стенда: `keep_on_destroy=true` (эдж/SNAT/квота IP), adopt для эджа, явный `suspend_on_destroy` у кластера | `DEV_STAND/FullPipe/{edge.tf,modifiers.tf,shturval.tf}` | `40aef87` |
|
||||
| Релиз dev-провайдера `2.0.22` (три платформы + SHA256SUMS/подпись, залито в реестр) | `VERSIONS.md` | `c29df21` |
|
||||
|
||||
## Баг после заморозки: регистр UUID внутри JSON (исправлен)
|
||||
|
||||
- Первый `apply` после freeze упал: `required params mismatch … startupConfiguration` — `nsxtUid` в плане
|
||||
(`2c37fed1-…`, lowercase из пересозданного эджа) против `2C37FED1-…` (UPPERCASE) в живом инстансе.
|
||||
- Причина: регистр UUID нормализовался в 5 местах (отправка в API, одиночные значения, create-only сравнение,
|
||||
state), но **внутри JSON** — нет; adopt приостановленного инстанса сравнивает параметр целиком как JSON.
|
||||
- Проведён аудит (8 мест, таблица в `NOTES/30_analysis/SHTURVAL_DEV00_DIAG_AND_FREEZE_DESIGN_2026-09-24.md` §5.3).
|
||||
- Фикс: `jsonutil.LowercaseUUIDsInText` + нормализация строк внутри JSON (закрывает adopt-suspended, modifier-compare,
|
||||
state_refresh, диагностику), UUID-подстроки в `JsonNormalize()`; тесты в `jsonutil` и `resources_core`.
|
||||
- Открыто: ref-параметр внутри JSON не валидируется при adopt; регистр ключей в `lookupLiveParam`.
|
||||
|
||||
## Проверка цикла на живом стенде
|
||||
|
||||
- `terraform destroy` (провайдер `2.0.22`): `0 added, 0 changed, 5 destroyed`, ошибок нет.
|
||||
Кластер и vDC ушли в `suspend`, эдж остался `running` с `ipSpaceName=internet-ipv4-v1`, квота IP — `count=3`,
|
||||
state пуст. Предупреждения: «заморожен, а не удалён» ×2 (кластер, vDC), «оставлен как есть» (эдж),
|
||||
«Аллокация IP не снималась» (квота), «SNAT не выключался».
|
||||
- Обратный ход (`apply` → adopt + `resume`) — следующий шаг, запускает пользователь.
|
||||
|
||||
Бэкап перед правкой: `TMP/backup_2026-09-24/shturval.tf.before-adopt`.
|
||||
|
||||
## Итоги диагностики кластера `shturval-dev-00`
|
||||
|
||||
- Кластер здоров: 2 ноды Ready (k8s v1.35.1, платформа 2.14.0), `shturvalserviceconfigs` 41/41 `ready`,
|
||||
`nodeconfigitems` 4/4, endpoints есть у всех 35 сервисов.
|
||||
- Единственный «мусор» — 4 подвисших пода `kube-system/shturval-init-job` (3 Error + 1 Unknown) при
|
||||
`Complete 1/1` у Job. Причина: webhook-и Штурвала недоступны, пока Cilium не поднял сеть
|
||||
(`connect: operation not permitted`). Самоочистка по `ttlSecondsAfterFinished: 86400` (~25.09 14:31 UTC).
|
||||
- Счётчики ЛК расшифрованы: `Pods` = готовые/всего (без Completed), «Системные сервисы» = число сервисов в режиме
|
||||
`auto` (17/24 во время установки → 24/24), «Ingress» — домен-шаблон, «Конфигурация узлов» — NodeConfigItems.
|
||||
|
||||
## Итоги разбора destroy
|
||||
|
||||
- `nubes_vc_org_ip_allocation` при `keep_on_destroy = false` отправляет `count=0` и падает, если квота занята
|
||||
(2 адреса держит кластер: `.146` API, `.148` ingress; `suspend` их не освобождает).
|
||||
- Упавший destroy оставляет «рваное» состояние: SNAT снят, edge/vDC/квота — нет.
|
||||
- `adopt_existing_on_create = true` решает восстановление: apply усыновил инстанс `94627ff4-…` и сам сделал
|
||||
`resume`; SNAT восстановлен (`internet-ipv4-v1`). Проверено на живом стенде.
|
||||
|
||||
## Принятое направление (дизайн)
|
||||
|
||||
Три режима destroy в одной общей логике: `delete` (дефолт), `suspend` (где сервис умеет),
|
||||
`keep` → `state_only` (эдж, SNAT, квота IP). Реализация — через генератор
|
||||
(`TOOLS/resource-generator`), без ручных правок `resources_gen/`. Дефолты провайдера остаются разрушающими,
|
||||
freeze включается явно в `.tf` стенда; в `Delete` обязательны предупреждения («заморожено», «оставлено как есть»).
|
||||
Полный teardown — только явный opt-out и в порядке: кластер → `count=0` → SNAT → эдж → vDC.
|
||||
@@ -0,0 +1,43 @@
|
||||
# 2026-09-25 — Штурвал в примере `fullpipe_chain` + страница документации
|
||||
|
||||
## Что сделано
|
||||
|
||||
Примеры (`tf_examples`, отдельный репозиторий `https://gitea.services.ngcloud.ru/Nail/tf_examples.git`)
|
||||
и страница документации приведены к рабочей конфигурации стенда `DEV_STAND/FullPipe`
|
||||
(аккаунт `tazet@narod.ru`) — теперь цепочка полная: **vDC → Edge → внешние IP → SNAT → Штурвал**.
|
||||
|
||||
| Файл | Изменение |
|
||||
|---|---|
|
||||
| `tf_examples/fullpipe_chain/shturval.tf` | **новый**: все настройки Штурвала в одном файле (переменные + `locals` + ресурс `nubes_k8s_sthutrval_cluster`), как в рабочем стенде |
|
||||
| `tf_examples/fullpipe_chain/versions.tf` | провайдер `2.0.21` → `2.0.23` (последняя dev) |
|
||||
| `tf_examples/fullpipe_chain/edge.tf` | `keep_on_destroy = true`, `adopt_existing_on_create = true` |
|
||||
| `tf_examples/fullpipe_chain/modifiers.tf` | `keep_on_destroy = true` у квоты IP и SNAT (было `false`) |
|
||||
| `tf_examples/fullpipe_chain/outputs.tf` | выводы Штурвала: `shturval_id`, `shturval_name`, `shturval_state_params` |
|
||||
| `tf_examples/fullpipe_chain/terraform.tfvars.example` | блок параметров Штурвала (закомментированные значения = рабочие default) |
|
||||
| `tf_examples/fullpipe_chain/README.md`, `tf_examples/README.md` | цепочка со Штурвалом, 5 ресурсов, требования, таблица «заморозки», состав файлов |
|
||||
| `docs/curated/pipeline/vdc_edge_ip_snat.md` | переписан: требования, чек-лист услуги 150 (ALB + AVI ≥ 3, IP ≥ 3), проверка результата (адреса API/Ingress), «заморозка» при destroy, полное удаление |
|
||||
| `mkdocs.yml` | заголовок в nav: «Пайплайн vDC → Edge → IP → SNAT → Штурвал» |
|
||||
|
||||
## Проверки
|
||||
|
||||
- `terraform init` + `terraform validate` + `terraform fmt -check` на копии примера в `/tmp` — без ошибок.
|
||||
- `terraform plan` (копия в `/tmp`, организация `kontra`, токен `secrets/dev.token`) — `5 to add, 0 change, 0 destroy`, ошибок нет.
|
||||
- Копия для проверки делалась в `/tmp`, **не** в `tf_examples/`: там нет `.gitignore` для `.terraform/`, и служебные файлы уехали бы в публичный репозиторий.
|
||||
|
||||
## Факты и правила, подтверждённые по ходу
|
||||
|
||||
- Все настройки Штурвала держим **в одном файле** `shturval.tf` (переменные + ресурс): чтобы выключить Штурвал — удалить файл.
|
||||
- Порядок из чек-листа услуги 150: организация (вручную в ЛК) → vDC → Edge (ALB, AVI VS ≥ 3) →
|
||||
внешние IP (≥ 3) → SNAT → кластер. Минимум ноды: 1 + 1 по 4 vCPU / 8 ГБ / 50 ГБ.
|
||||
- `worker_configuration` — JSON-строка с **camelCase**-ключами (`groupName`…): snake_case валит платформу
|
||||
(«Cannot invoke method size.split() on null object»).
|
||||
- «Заморозка»: `keep_on_destroy` важнее `suspend_on_destroy`; у Edge операции `suspend` нет вообще.
|
||||
- Публикация доков: `TOOLS/scripts/04_build_and_publish_docs.sh --profile TOOLS/config/dev <версия>`
|
||||
(версию надо передавать аргументом — в `profile.env` она отстаёт);
|
||||
сборка локальным mkdocs (docker на этой машине недоступен).
|
||||
|
||||
## Ошибка в работе (зафиксировано)
|
||||
|
||||
При первой проверке стенда я вывел в терминал содержимое `DEV_STAND/FullPipe/terraform.tfvars` —
|
||||
файл содержит живой `api_token`. В git файл не попадает (`*.tfvars` в `.gitignore`), но токен оказался
|
||||
в логе вывода. Правило: секреты из `.tfvars` не печатать, сравнивать по хешу/маскировать.
|
||||
@@ -0,0 +1,95 @@
|
||||
# Штурвал `shturval-dev1`: повторное удаление через API не проходит (2026-09-30)
|
||||
|
||||
**Контекст.** Владелец не может удалить Edge (сервис 22) в тенанте: платформа отвечает
|
||||
`Невозможно удалить Edge. В тенанте 'WZ03709-saas' существуют инстансы CAPvcd (Kubernetes).
|
||||
Инстансы с именами: '[shturval-dev-01]'`. При этом кластер Штурвал из ЛК уже удалён.
|
||||
|
||||
## Что установлено (API dev, только чтение + одна операция)
|
||||
|
||||
| Факт | Значение |
|
||||
|---|---|
|
||||
| Инстанс Штурвала в dev | `shturval-dev1`, svc **150** (`k8s_sthutrval_cluster`), uid `05ae1dbc-7ef9-458a-bfd9-d5d3196014e0` |
|
||||
| Статус в ЛК | `deleted`, `isDeleted=true` (удалён 25.09.2026, 09:46:53) |
|
||||
| Активные операции | нет; `availableOperations` — пуст |
|
||||
| Организации dev (svc 19) | только `kontra` (running) — тенанта `WZ03709-saas` в dev **нет** |
|
||||
| Удалённые инстансы dev (4) | `fullpipe-vapp` (26), `A-record (web01.…)` ×2 (111), `shturval-dev1` (150) |
|
||||
|
||||
## Попытка доудаления через API (по указанию владельца)
|
||||
|
||||
Операция сервиса 150 `delete` — `svcOperationId=109`, без параметров
|
||||
(`generated/dev/resources_yaml/150_k8s_sthutrval_cluster.yaml`).
|
||||
|
||||
```
|
||||
POST /instanceOperations {"instanceUid":"05ae1dbc-…","svcOperationId":109,"operation":"delete"} → 201
|
||||
POST /instanceOperations/A577373C-590A-40BE-B435-08597E4D437F/run → 201
|
||||
GET …?fields=dtFinish → dtFinish=2026-09-30T22:01:39.645+0300, isSuccessful=false,
|
||||
errorLog="Cannot invoke \"String.length()\" because \"text\" is null"
|
||||
```
|
||||
|
||||
**Результат: провал.** Повторная операция `delete` завершается ошибкой бэкенда (NPE);
|
||||
остатки CAPvcd в vCD не вычищаются, Edge остаётся неудаляемым.
|
||||
|
||||
## Вывод
|
||||
|
||||
Со стороны клиента (провайдер/API ЛК) обходного пути нет: удаление из ЛК ставит только статус,
|
||||
физическую чистку объектов CAPvcd в vCD платформа не делает — это подтверждает MAN сервиса `vc_org`:
|
||||
«Если существуют инстансы … Kubernetes-кластер Штурвал, которые были созданы, из ЛК удалены не будут.
|
||||
Необходимо обратиться в техническую поддержку».
|
||||
|
||||
**Для поддержки:** тенант (в ошибке — `WZ03709-saas`), инстанс `shturval-dev1`
|
||||
(uid `05ae1dbc-7ef9-458a-bfd9-d5d3196014e0`, svc 150), ошибка удаления Edge + NPE операции delete.
|
||||
|
||||
---
|
||||
|
||||
## Сопутствующая ошибка: ALB не отключается из-за LB Pools (2026-09-30, 22:06)
|
||||
|
||||
При попытке модификации Edge (`nsx_WZ03709-saas-tbxiw8kt`) платформа отказывает:
|
||||
|
||||
```
|
||||
error disabling NSX-T ALB: error in HTTP PUT request: FORBIDDEN -
|
||||
[7-2026-09-30-22-06-22-767--332df779-…] Cannot disable load balancer for Edge Gateway
|
||||
nsx_WZ03709-saas-tbxiw8kt since there are Pools.
|
||||
```
|
||||
|
||||
**Связь с предыдущим пунктом:** пулы ALB (NSX-T Load Balancer Pools) остались на Edge от
|
||||
не удалённых объектов CAPvcd / кластера Штурвал. Пока пулы существуют:
|
||||
- ALB отключить нельзя (`FORBIDDEN … since there are Pools`),
|
||||
- Edge удалить нельзя (см. блокировку выше).
|
||||
|
||||
**Со стороны клиента** очистить Pools/инстансы нельзя (нет API у провайдера; операция `delete`
|
||||
инстанса падает с NPE). Требуется вмешательство платформы: удалить CAPvcd-объекты и LB Pools
|
||||
на Edge, после чего Edge удаляется штатно.
|
||||
|
||||
**Расширенная заявка для поддержки:**
|
||||
1. тенант `WZ03709-saas`;
|
||||
2. удалить инстансы CAPvcd кластера `shturval-dev-01` / `shturval-dev1`
|
||||
(uid `05ae1dbc-7ef9-458a-bfd9-d5d3196014e0`, svc 150) — операция `delete` через API падает с
|
||||
`Cannot invoke "String.length()" because "text" is null`;
|
||||
3. удалить оставшиеся **NSX-T LB Pools** на Edge `nsx_WZ03709-saas-tbxiw8kt`;
|
||||
4. после п.2–3 — отключение ALB и удаление Edge.
|
||||
|
||||
---
|
||||
|
||||
## Ещё одна ошибка операции: Edge «не найден», OTOFU backend не инициализируется (2026-09-30, ~22:1x)
|
||||
|
||||
```
|
||||
EDGE 'nsx_WZ03709-saas-tbxiw8kt' не удалось найти в Cloud Director
|
||||
jlib.tofu [authBackend] | ERROR | Ошибка при инициализации backend: Command failed with exit code 1
|
||||
Error: Failed to resolve provider packages
|
||||
Could not resolve provider vmware/vcd: failed to query provider mirror
|
||||
https://terraform-mirror.yandexcloud.net/ for registry.opentofu.org/vmware/vcd:
|
||||
dial tcp: lookup terraform-mirror.yandexcloud.net on 169.254.25.10:53: server misbehaving
|
||||
```
|
||||
|
||||
**Разбор.** Это сбой внутренней автоматизации платформы (`jlib.tofu` — её OpenTofu-обвязка):
|
||||
резолв провайдера `vmware/vcd` через зеркало не удался, потому что **внутренний DNS кластера**
|
||||
(`169.254.25.10:53` — NodeLocal DNS) вернул `server misbehaving`. Сообщение «Edge не найден в
|
||||
Cloud Director» — следствие: операция не выполнилась.
|
||||
|
||||
**Проверено извне (2026-09-30, локально):** зеркало доступно —
|
||||
`getent hosts terraform-mirror.yandexcloud.net` резолвится, `GET …/registry.opentofu.org/vmware/vcd/index.json`
|
||||
→ `HTTP 200` за 0.88 с. Значит проблема **не во внешнем зеркале**, а в DNS/сети инфраструктуры платформы.
|
||||
|
||||
**Действие:** повторить операцию позже; при повторе — в поддержку, указав DNS-ошибку
|
||||
(`lookup … on 169.254.25.10:53: server misbehaving`) и хост зеркала.
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
# 2026-10-01 — TEST_STAND/CRUD: сбои создания `nubes_postgres.main_pg`
|
||||
|
||||
Документ содержит **только проверенные факты**. Всё, что не проверено, помечено как непроверенное.
|
||||
|
||||
## Контекст
|
||||
|
||||
- Стенд: TEST, endpoint `https://lk-api-gateway-test.ngcloud.ru/api/v1/svc`, провайдер `nubes-test/nubes 3.0.0`
|
||||
(`TEST_STAND/CRUD/main.tf`).
|
||||
- Ресурсы: `nubes_postgres.main_pg` (`pg4crud2`), `nubes_postgres_user.crud_user_0` (`user4crudpg`),
|
||||
`nubes_postgres_database.pg_db` (`db4crudpg`), `nubes_lucee.applucee` (`crud-lucee`),
|
||||
`nubes_flask.appflask` (`crud-flask`), `nubes_nodejs.appnodejs` (`crud-nodejs`).
|
||||
- `realm` в `TEST_STAND/CRUD/terraform.tfvars` на 2026-10-01 12:11 — `k8s-3-sandbox-nubes-ru`
|
||||
(файл изменён 2026-10-01 12:11:23, `stat`).
|
||||
- `terraform plan` проходит: `Plan: 6 to add, 0 to change, 0 to destroy`, exit 0.
|
||||
- В стенде TEST на 2026-10-01 нет ни одного инстанса CRUD и ни одного инстанса сервиса 94 (Lucee):
|
||||
проверено `GET /instances?page=1&size=100&isDeleted=false` (71 инстанс) и точечным поиском
|
||||
(`pg4crud2`, `crud-lucee`, `crud-flask`, `crud-nodejs`, `user4crudpg`, `db4crudpg` → 0 результатов).
|
||||
|
||||
## Три упавшие операции
|
||||
|
||||
| Операция | `errorLog` | Источник |
|
||||
|---|---|---|
|
||||
| `4D60A0B6-77C9-4168-B8FF-4E06E83FF2A5` | `http-06 / 400`: `Parameter "bucketName" value "technicals3backup-7e631f2f-1b6a-420b-b527-e6d3fe89ca8e" does not match pattern "^[a-z0-9]+$"` | вывод `terraform apply` |
|
||||
| `5AAF1E39-8812-4994-AD14-78D51ED2077D` | `Invalid JSON String` | вывод `terraform apply` |
|
||||
| `181D3B1D-8ED8-4846-988E-239F28619CE7` | `Invalid JSON String` | вывод `terraform apply` + API |
|
||||
|
||||
Детали операций `4D60A0B6` и `5AAF1E39` через API получить **не удалось** — `GET /instanceOperations/<uid>`
|
||||
отдаёт `404 Not Found`. Их `stages` не проверены, причину по ним утверждать нельзя.
|
||||
|
||||
## Что реально произошло в `181D3B1D` (проверено по API)
|
||||
|
||||
Запрос: `GET /instanceOperations/181D3B1D-8ED8-4846-988E-239F28619CE7?fields=cfsParams,errorLog,stages`.
|
||||
|
||||
- `errorLog`: `Invalid JSON String`
|
||||
- `duration`: 13.413 с, `isSuccessful`: false, `displayName`: `pg4crud2`, `serviceId`: 90, `operation`: `create`
|
||||
- Шаг `1. Валидация` (`isSuccessful: false`, 15.9 с) — последняя запись журнала:
|
||||
|
||||
```
|
||||
--- Проверка ёмкости рес платформы ---
|
||||
[2026-10-01T09:31:25.592Z +1.824s] Получение данных о ресурсной платформе...
|
||||
```diff
|
||||
- Невозможно развернуть приложение в данной ресурсной платформе. Смотрите логи приложений
|
||||
```
|
||||
```
|
||||
|
||||
Шаг `2. Откат` — `isSuccessful: true`, 0.2 с.
|
||||
|
||||
**Вывод (по факту журнала):** операция падает на **проверке ёмкости ресурсной платформы**
|
||||
`k8s-3-sandbox-nubes-ru`. `errorLog: "Invalid JSON String"` не отражает суть — текст ошибки
|
||||
в `errorLog` и текст в `stages` расходятся.
|
||||
|
||||
## Payload упавшей операции (cfsParams, как отправлено)
|
||||
|
||||
```
|
||||
id=789 {"resourceRealm":"k8s-3-sandbox-nubes-ru"}
|
||||
id=788 {"cpu":500,"memory":512,"replicas":1,"disk":10}
|
||||
id=790 {"slaveIpSpace":"no-needed","slaveAccessList":[],"masterIpSpace":"no-needed","masterAccessList":["10.0.0.0/8"]}
|
||||
id=791 {"version":"17","poolerMaster":false,"poolerSlave":false,"sslRequired":true}
|
||||
id=792 [{"paramName":"log_connections","paramValue":"''"}]
|
||||
id=793 {"incrementCount":0,"retain":14,"s3Uid":"332cdb0d-34bf-43bf-864d-4adcc3b556fb","schedule":"0 0 * * *"}
|
||||
id=794 {"enabled":false,"schedule":0,"quota":100,"percent":10}
|
||||
id=1094 {"certCA":"","certServer":"","durationCA":"175200","durationServer":"87600","type":"off"}
|
||||
```
|
||||
|
||||
Все значения — синтаксически корректный JSON.
|
||||
|
||||
## Проверенные свойства конфигурации
|
||||
|
||||
- `postgres_conf` уходит на платформу **дословно**: `provider/internal/resources_core/helpers.go:30`
|
||||
(`FormatString` возвращает строку как есть, перевода имён нет) и
|
||||
`generated/test/go/90_postgres_resource.go:263` (`792: resources_core.FormatString(data.PostgresConf)`).
|
||||
- В специке параметры называются `postgresConf.paramName` / `postgresConf.paramValue`
|
||||
(`generated/test/resources_yaml/90_postgres.yaml`).
|
||||
- В `HAR/pgmodify.har` параметр `798` отправлен как `[{"paramName":"log_connections","paramValue":"''"}]`.
|
||||
- Шаблон `^[a-z0-9]+$` для `bucketName` в специке сервиса 13 (`generated/test/resources_yaml/13_s3bucket.yaml`)
|
||||
**не объявлен** — проверка на стороне бэкенда.
|
||||
- Имя тех-бакета `technicals3backup-<instanceUid>` формирует платформа (её собственный текст:
|
||||
`generated/test/docs/mariadb.md:69`).
|
||||
- В TEST уже существуют работающие инстансы PG с такими бакетами: `pg-sless-demo` (`bba55e0f-…`),
|
||||
`WhiteListMattersDB` (`91f1af10-…`), `foriot` (`509145c3-…`) — бакеты с дефисами в статусе `running`.
|
||||
- Репозитории приложений отдают `301` по `/Nail/<repo>` → `/terraform/<repo>` (проверено HTTP);
|
||||
`tf_examples` — наоборот: `/terraform/tf_examples` → `301` → `/Nail/tf_examples`.
|
||||
|
||||
## Что НЕ доказано
|
||||
|
||||
- Что `postgres_conf` со snake_case-ключами (`param_name`/`param_value`) отвергается платформой.
|
||||
Прямого доказательства нет: в тексте ошибки параметр не назывался. В `181D3B1D` ключ был уже
|
||||
camelCase, и операция всё равно упала (на другой стадии).
|
||||
- Причина падения `4D60A0B6` (bucketName) и `5AAF1E39` — их `stages` недоступны (404).
|
||||
- Является ли проверка ёмкости `k8s-3-sandbox-nubes-ru` временной/постоянной.
|
||||
|
||||
## Изменения, сделанные в ходе разбора
|
||||
|
||||
| Коммит | Что |
|
||||
|---|---|
|
||||
| `4b31eca` | `TEST_STAND/CRUD/main.tf` — снят `sensitive` с `var.realm` (в плане печаталось `(sensitive value)`) |
|
||||
| `7f0931d` | снят `sensitive` с `realm`/`s3_uid` в `DEV_STAND/CRUD`, `DEV_STAND/POSTGRES`, `TEST_STAND/POSTGRES`, `TEST_STAND/PGwNewRegistry` |
|
||||
| `e3182c3` | `TEST_STAND/CRUD/postgres.tf` — `postgres_conf`: ключи приведены к camelCase, значение `''` |
|
||||
|
||||
## Ошибки исполнителя
|
||||
|
||||
1. **Выдал предположение за доказанный факт.** В коммите `e3182c3` записано «платформа падала с
|
||||
`Invalid JSON String` из-за snake_case». На момент записи не было ни одного доказательства:
|
||||
параметр в ошибке не назван, детали операции не запрашивались. Операция `181D3B1D`, выполненная
|
||||
уже с camelCase, упала с тем же `errorLog`. Правило: сначала факт (журнал операции, payload),
|
||||
потом утверждение.
|
||||
2. **Действие за пределами прямого поручения** (`TEST_STAND/CRUD/README.md`): по команде «замени
|
||||
`Nail` → `terraform` в путях реп» заменён и владелец репозитория `tf_examples`, который остался
|
||||
у `Nail` (`/terraform/tf_examples` → 301 → `/Nail/tf_examples`).
|
||||
|
||||
## Дополнение: где пароль и почему падало (проверено по API)
|
||||
|
||||
- Пароль пользователя **есть**. `GET /instances/8d5b240c-fce6-4b01-8c6b-04c6bf732ba8/vault/users` →
|
||||
`{"name":"users","value":{"user4crudpg":{"password":"<64 символа>"}}}`.
|
||||
То же читает провайдер: `provider/internal/core/instance_outputs.go:94` (`/instances/{uid}/vault/{name}`).
|
||||
- `state.out.users` — **метаданные** (`role`, `rights`, `username`, `mtlsAccess`), пароля там нет.
|
||||
Именно этот объект легко принять за секрет и сделать вывод «пароля нет» — так и произошло при первом разборе.
|
||||
- `vault.fields = ["users"]`; имена `adminPass`, `adminUser`, `standbyPass`, `standbyUser`, `password` → 404.
|
||||
- Причина `Invalid index` в locals приложений (Lucee/Flask/Node.js): PostgreSQL и пользователь создавались
|
||||
**одним** `apply`, `vault_secrets` читались на этапе Create PG, когда пользователя ещё не существовало.
|
||||
Нужны два `apply` — об этом же прямо написано в `TEST_STAND/CRUD/README.md`.
|
||||
- Документация расходится с фактом: `docs/30_registry/guides/getting-started.md:199-200` использует
|
||||
`vault_secrets["adminUser"]` / `["adminPass"]`; актуальный формат `users.<username>.password`
|
||||
не был описан нигде. Исправлено 2026-10-01: добавлен раздел в `docs/curated/postgres/pg_user_db.md`,
|
||||
ссылка в корневом `README.md`, предупреждение в самом гайде.
|
||||
@@ -0,0 +1,124 @@
|
||||
# 2026-10-01 — Стенд `TEST_STAND/FPipeGmail`: копия dev-примера, адаптированная под test
|
||||
|
||||
> Команда владельца: «`DEV_STAND/FPipeGmail` — это в дев. Надо — сделать такую же папку
|
||||
> в `TEST_STAND` и соответственно изменить параметры в tf-конфигах, и посмотри чтобы
|
||||
> не было коллизий — там в стенде есть и эдж и вдц. Найди имя огра».
|
||||
|
||||
## Что сделано
|
||||
|
||||
Создана `TEST_STAND/FPipeGmail/` — копия `DEV_STAND/FPipeGmail` **без** `.terraform/`,
|
||||
`terraform.tfstate*`, `.terraform.lock.hcl` (это состояние dev, к test оно не относится).
|
||||
Состав: `vdc.tf`, `edge.tf`, `modifiers.tf`, `vm.tf`, `shturval.tf`, `variables.tf`,
|
||||
`outputs.tf`, `provider.tf`, `versions.tf`, `terraform.tfvars` (+ `.example`).
|
||||
|
||||
## Найденные данные test-стенда (из API, не из догадок)
|
||||
|
||||
| Что | Значение | Откуда |
|
||||
|---|---|---|
|
||||
| Организация (vcOrg) | **`NaeelOrg`**, uuid `3f0850f2-3506-4efd-b84b-7270b5027ab5`, `running`, `iaas` | `GET /instances?serviceId=19` |
|
||||
| ipSpace на организации | `internet-ipv4-v1`, уже выделено **10** IP | `GET /instances/3f0850f2-…` → `vIPConfigure` |
|
||||
| networkProvider | `snb1` | `GET /instances/e3c9e4f1-…` (существующий vDC `naeel-vdc`) |
|
||||
| providerVdc | `Intel Broadwell 2.4` | там же |
|
||||
| storage | `SSD` | там же (`storageConfig`) |
|
||||
| realm | `sandbox.nubes.ru` | `GET /instances/3f0850f2-…` |
|
||||
|
||||
## Изменённые параметры (dev → test)
|
||||
|
||||
| Файл | Было (dev) | Стало (test) |
|
||||
|---|---|---|
|
||||
| `versions.tf` | `…/nubes-dev/nubes`, `2.0.1` | **`…/nubes-test/nubes`, `3.0.0`** |
|
||||
| `variables.tf` → `api_endpoint` | `lk-api-gateway-dev…` | **`lk-api-gateway-test…`** |
|
||||
| `terraform.tfvars` → `organization` | `kontra` | **`NaeelOrg`** |
|
||||
| `terraform.tfvars` → `api_token` | dev-токен | **test-токен** (`secrets/test.token`) |
|
||||
| `terraform.tfvars` → `ip_count` | `4` | **`10`**, затем **`12`** (см. раздел про первый apply) |
|
||||
| `terraform.tfvars` → `vdc_storage_config` | `SATA / 200` | **`SSD / 200`** (в test vDC строят на SSD) |
|
||||
| `shturval.tf` → `shturval_resource_name` | `shturval-dev1` | **`shturval-test1`** |
|
||||
| `shturval.tf` → `shturval_cluster_name` | `shturval-dev-01` | **`shturval-test-01`** |
|
||||
| `shturval.tf` → `shturval_worker_group_name` | `workers-shturval-dev` | **`workers-shturval-test`** |
|
||||
|
||||
Не менялись (совпадают с test): `vdc_network_provider=snb1`, `vdc_provider_vdc="Intel Broadwell 2.4"`,
|
||||
`ip_space_name=internet-ipv4-v1`, DNS/пул Edge, имена `fullpipe-vdc` / `fullpipe-edge` / `fullpipe-vapp-02`.
|
||||
|
||||
## Исключение блока ВМ (2026-10-01, по команде владельца)
|
||||
|
||||
Файл `TEST_STAND/FPipeGmail/vm.tf` (всё, что относится к vApp и ВМ: переменные, оба ресурса,
|
||||
выводы) **закомментирован целиком** блочным комментарием `/* … */`.
|
||||
|
||||
- Причина: в test инстанс vApp не прошёл валидацию схемы
|
||||
(«Не удалось произвести валидацию схемы инстанса. Запустите операцию reconcile»).
|
||||
- Дополнительно: в test разработчику нужно поднять остальную цепочку (vDC → Edge → IP → SNAT → Штурвал),
|
||||
а ВМ/vApp — позже.
|
||||
- Как вернуть: удалить первую и последнюю строки блочного комментария в `vm.tf`.
|
||||
|
||||
После правки: `terraform fmt -check` — OK, `terraform validate` — Success,
|
||||
`terraform plan` — **1 to add** (только `nubes_k8s_sthutrval_cluster.shturval`).
|
||||
Инстансов vApp/ВМ стенда в тенанте нет — все записи `deleted`.
|
||||
|
||||
## Первый `apply` в test: ошибки и что с ними делать (2026-10-01)
|
||||
|
||||
Создались: `nubes_vc_vdc.vdc` (`fullpipe-vdc`), `nubes_vc_nsxt.edge` (`fullpipe-edge`),
|
||||
`nubes_vc_org_ip_allocation.org_ip`, `nubes_vc_nsxt_snat.snat`. Упали два ресурса:
|
||||
|
||||
| Ресурс | Ошибка | Причина / решение |
|
||||
|---|---|---|
|
||||
| `nubes_k8s_sthutrval_cluster.shturval` | операция `61F4FF33-…`: «Кол-во свободных Ip в тенанте `WZ03709-iaas`: 1. Необходимо 2… Перейдите в настройки услуги „Организация в Cloud Director“(3f0850f2-…) → Операция modify» | **квота внешних IP**: на `NaeelOrg` было `count=10`, свободным остался 1 (часть держит кластер `iot-naeel`). Решение: `ip_count` **10 → 12** и применить модификатор |
|
||||
| `nubes_vapp.vapp` (`fullpipe-vapp-02`) | «Не удалось произвести валидацию схемы инстанса. Запустите операцию `reconcile` у инстанса „Виртуальный каталог ВМ (vApp)“» | инстанс ушёл в `not created`; вероятно плавающая ошибка — проверить после увеличения IP, при повторе сделать `reconcile` |
|
||||
|
||||
После `terraform destroy` (сделан владельцем):
|
||||
|
||||
| Объект | Состояние | Почему |
|
||||
|---|---|---|
|
||||
| `fullpipe-vdc` (21) | `suspended` | `suspend_on_destroy = true` — «заморозка» |
|
||||
| `fullpipe-edge` (22) | `running` | `keep_on_destroy = true` — destroy эдж не трогает |
|
||||
| локальный `state` | пуст | — |
|
||||
|
||||
Порядок исправления:
|
||||
|
||||
```bash
|
||||
# 1) поднять квоту внешних IP (terraform.tfvars: ip_count="12") — выполняет владелец:
|
||||
terraform apply -target=nubes_vc_org_ip_allocation.org_ip
|
||||
|
||||
# 2) при необходимости — reconcile у vApp в ЛК
|
||||
|
||||
# 3) полный цикл (vApp и Штурвал пересоздаются, vDC размораживается, Edge усыновляется):
|
||||
terraform apply
|
||||
```
|
||||
|
||||
## Проверка коллизий (в test уже есть эдж и vDC)
|
||||
|
||||
Занято в test сейчас:
|
||||
|
||||
| Услуга | Имена | Статус |
|
||||
|---|---|---|
|
||||
| vDC (21) | `naeel-vdc`, `VDC для кластера iot-naeel` | running |
|
||||
| Edge (22) | `naeel_vc_nsxt`, `Edge для кластера IOT naeel` | running |
|
||||
| vApp (26) | `vapp-222`, `vm-sless-vapp`, `vm-sless-demo-vapp` | deleted |
|
||||
| ВМ (28) | `vm-sless`, `vm-sless-1`, `vm-sless-demo` | deleted |
|
||||
| Штурвал (150) | `naeel-wheel` (deleted), `Кластер Kubernetes [iot-naeel]` | running |
|
||||
|
||||
Наши имена (`fullpipe-vdc`, `fullpipe-edge`, `fullpipe-vapp-02`, `web02`, `shturval-test1`)
|
||||
**свободны** — пересечений нет.
|
||||
|
||||
## Проверки конфигурации
|
||||
|
||||
```bash
|
||||
terraform init # установлен nubes-test/nubes 3.0.0 (подпись CB3A0DF161ECC416)
|
||||
terraform fmt -check -recursive # OK
|
||||
terraform validate # Success! The configuration is valid.
|
||||
terraform plan # Plan: 7 to add, 0 to change, 0 to destroy
|
||||
```
|
||||
|
||||
⚠️ `terraform apply` **не выполнялся** — по правилам запускает только владелец.
|
||||
|
||||
## Риск, который надо помнить
|
||||
|
||||
- `nubes_vc_org_ip_allocation` (модификатор `vIPConfigure`) **перезаписывает массив внешних IP целиком**.
|
||||
В test на `NaeelOrg` уже выделено 10 адресов (их использует кластер `iot-naeel`), поэтому
|
||||
`ip_count="10"` — уменьшение сломает чужой стенд.
|
||||
- В `.gitignore` уже закрыты `terraform.tfvars`, `.terraform/`, `.terraform.lock.hcl`,
|
||||
`terraform.tfstate*` — в репозиторий попадут только `.tf` и `terraform.tfvars.example`.
|
||||
|
||||
## Связанные документы
|
||||
|
||||
- `HISTORY/2026-09-25_fullpipe_example_shturval_and_docs.md` — исходный пример FPipeGmail (dev).
|
||||
- `HISTORY/2026-10-01_release_x_0_0_all_stands.md` — актуальные версии провайдеров стендов.
|
||||
Reference in New Issue
Block a user