From ebbba6614617d00cf5c88681943ffeb4ed424461 Mon Sep 17 00:00:00 2001 From: Repinoid Date: Wed, 1 Apr 2026 19:21:37 +0400 Subject: [PATCH] doc: pg-terraform behavior report + ERR-PG-06/07 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - doc/pg-terraform-behavior.md: подробный отчёт по поведению Nubes PostgreSQL с Terraform (vault_secrets, роли, тайминги, depends_on chain, SSH timeout) Добавлены: §2.6 vault ограничение (только 1 пользователь на инстанс), §9 IAM 408 - doc/errors/log.md: ERR-PG-01..ERR-PG-07 (все ошибки сессии тестирования) ERR-PG-06: vault backend позволяет только 1 vault_secrets на инстанс ERR-PG-07: HTTP 408 от auth-api-test.ngcloud.ru (транзитная) - doc/progress.md: финальный статус сессии — lifecycle тесты заблокированы vault-ограничением тест-окружения, требуется исправление на стороне Nubes --- doc/errors/log.md | 244 ++++++++++++++++++++++++ doc/pg-terraform-behavior.md | 359 +++++++++++++++++++++++++++++++++++ doc/progress.md | 98 +++++++++- 3 files changed, 700 insertions(+), 1 deletion(-) create mode 100644 doc/pg-terraform-behavior.md diff --git a/doc/errors/log.md b/doc/errors/log.md index c90155c..59f4b4f 100644 --- a/doc/errors/log.md +++ b/doc/errors/log.md @@ -4,6 +4,250 @@ --- +## 2026-04-01 — Nubes PostgreSQL API: ошибки при создании ресурсов (PG_TEST) + +Все ошибки воспроизводились в `examples/PG_TEST` при тестировании провайдера +`terra.k8c.ru/nubes/nubes` v5.0.51. VM: `naeel@5.172.178.213`, PG-инстанс: `pg-test-02`. + +--- + +### ERR-PG-01: "Invalid JSON String" при создании инстанса с json_parameters + +**Симптом** + +``` +Error: Ошибка клиента + with nubes_postgres.pg_test_instance + Invalid JSON String +``` + +**Причина** + +При передаче параметра `json_parameters` (строка JSON с кастомными настройками PG) +Nubes API v5 возвращает "Invalid JSON String" независимо от корректности самого JSON. +Вероятно — баг в провайдере или несовместимость формата с deck-api-test. + +**Решение** + +Убран `json_parameters` из конфигурации `nubes_postgres`. PG запускается +с дефолтными параметрами движка. При необходимости custom params — требует +диагностики на стороне Nubes (`.api_endpoint = deck-api-test.ngcloud.ru`). + +**Файл:** [examples/PG_TEST/postgres.tf](examples/PG_TEST/postgres.tf) + +--- + +### ERR-PG-02: vault_secrets меняется вне Terraform → destroy+recreate всей цепочки + +**Симптом** + +Каждый `terraform apply` обнаруживает изменения "снаружи Terraform": + +``` +Note: Objects have changed outside of Terraform + # nubes_postgres.pg_test_instance has changed + ~ vault_secrets = (sensitive value) +``` + +Это вызывает план с `-/+ destroy and then create replacement` для `pg_test_user` +и `pg_test_db`, хотя реально они не изменились. + +**Причина** + +Nubes API обновляет `vault_secrets` (путь к Vault с паролями пользователей) +каждый раз при создании/удалении пользователей. Terraform видит это как +"изменение снаружи" и считает `postgres_id` изменённым (т.к. он `(known after apply)` +после обновления инстанса), что форсирует замену всех дочерних ресурсов. + +**Попытка решения** + +Добавить `lifecycle { ignore_changes = [vault_secrets] }` — **не работает**. +Terraform выводит предупреждение: +> "The attribute vault_secrets is decided by the provider alone and therefore +> there can be no configured value to compare with. Including this attribute +> in ignore_changes has no effect." + +`vault_secrets` — Computed-only (провайдер его полностью контролирует), +`ignore_changes` для таких атрибутов игнорируется. + +**Реальная причина** destroy+recreate: при обнаружении `vault_secrets` как +"изменённого снаружи" Terraform обновляет `nubes_postgres` in-place, но +в плане ставит `id = (known after apply)` — это форсирует замену зависимых +ресурсов у которых `postgres_id` ссылается на `nubes_postgres.*.id`. + +**Статус: открытая проблема.** Обходной путь — выполнять `apply` только на +чистом state (без накопленных изменений снаружи). После первого полного +`apply` с `lifecycle ignore_changes` убран как неэффективный. + +**Файл:** [examples/PG_TEST/postgres.tf](examples/PG_TEST/postgres.tf) + +--- + +### ERR-PG-03: Race condition при параллельном создании пользователей + +**Симптом** + +При одновременном создании двух и более `nubes_postgres_user` на одном инстансе: + +``` +Error: Ошибка клиента + with nubes_postgres_user.test_extra_user1 + операция XXXX завершилась с ошибкой: Секрет для пользователя extra_user1 не был создан +``` + +Или: + +``` + операция XXXX завершилась с ошибкой: key doesn't exist +``` + +**Причина** + +Nubes API не поддерживает параллельное создание пользователей на одном PG-инстансе. +Внутри Nubes: каждое создание пользователя пишет в Vault, а Vault/Deck +не справляются с конкурентными записями в один Secret. + +**Решение** + +Принудительная последовательная цепочка через `depends_on`: + +``` +pg_test_user → pg_test_db → extra_user1 → extra_user2 → extra_db1 → extra_db2 +``` + +Каждый `nubes_postgres_user` и `nubes_postgres_database` явно ждёт предыдущий. +`depends_on` нужен даже если прямой ссылки на атрибуты нет. + +**Файлы:** [examples/PG_TEST/postgres.tf](examples/PG_TEST/postgres.tf), +[examples/PG_TEST/postgres_extra.tf](examples/PG_TEST/postgres_extra.tf) + +--- + +### ERR-PG-04: Роль app_user не работает для nubes_postgres_user + +**Симптом** + +``` +Error: Ошибка клиента + with nubes_postgres_user.test_app_user, + операция XXXX завершилась с ошибкой: Секрет для пользователя test_app_user не был создан +``` + +Ресурс висит ~3 минуты перед ошибкой. Воспроизводится стабильно. + +**Причина** + +Роль `app_user` не поддерживается для создания PostgreSQL пользователей +через `nubes_postgres_user` в данной версии провайдера/API. Возможно, роль +предусмотрена только для другого механизма доступа. + +**Решение** + +Использовать только роль `ddl_user` для ресурса `nubes_postgres_user`. +Создание пользователей с `app_user` — не работает на `deck-api-test.ngcloud.ru`. + +Из конфигурации удалён ресурс `nubes_postgres_user.test_app_user`. + +--- + +### ERR-PG-05: "Нарушена консистентность" — пользователь есть в API, нет в state_out + +**Симптом** + +``` +Error: Нарушена консистентность + with nubes_postgres_user.test_extra_user1 + Операция вернула duplicate/exist, но объект не найден в state_out +``` + +**Причина** + +Пользователь `extra_user1` был создан Nubes API на предыдущей (упавшей) попытке apply. +Terraform state не зафиксировал успех (т.к. apply завершился ошибкой), но Nubes +счётной записью `extra_user1` не удалил. + +Флаг `adopt_existing_on_create = true` должен был решить это, но он проверяет +`state_out` инстанса — а там пользователь не отражается (из-за ERR-PG-02: +`vault_secrets` изменялся и инстанс был в "changed outside" состоянии). + +**Решение** + +Полный `terraform destroy` для очистки state + ресурсов в API, затем +`terraform apply` с уже включённым `lifecycle { ignore_changes = [vault_secrets] }`. +После этого проблема не воспроизводится. + +--- + +### ERR-PG-06: Второй пользователь на инстансе не может получить vault_secrets + +**Симптом** + +При создании второго пользователя на PG-инстансе (первый уже существует): + +``` +Error: Ошибка клиента + with nubes_postgres_user.test_extra_user1 + операция 4D816F17-F43E-4062-AE37-5098ADE07041 завершилась с ошибкой: + Секрет для пользователя test_eu1 не был создан +``` + +Ресурс висит ~3–4 минуты, затем падает с этой ошибкой. Воспроизводится стабильно +для любого второго пользователя (проверено на `extra_user1`, `test_eu1`) +независимо от роли (`ddl_user`), имени и порядка depends_on. + +**Важно**: `pg_test_user` (первый пользователь, созданный при инициализации +инстанса) всегда успешно проходит через adoption за 1 секунду — его vault_secret +уже был создан при первом apply. Только создание **нового** второго пользователя +всегда приводит к этой ошибке. + +**Причина** + +Vault backend для PG-инстанса `e0e74801` (тест-окружение `k8s-3-sandbox-nubes-ru`) +вероятно ограничен одной vault-записью на инстанс. При попытке создать vault_secrets +для второго пользователя — запись не создаётся, провайдер возвращает ошибку через +~3–4 минуты ожидания. + +Либо vault policy для данного инстанса предусмотрена только для основного +пользователя (`user0`). Дополнительные пользователи не имеют прав vault-path. + +**Статус: открытая проблема, требует диагностики на стороне Nubes.** + +**Следствие для архитектуры**: +В текущем тест-окружении Nubes PostgreSQL поддерживает **только одного пользователя +с vault_secrets** на инстанс. Lifecycle-тесты с несколькими пользователями +(**goal** текущей сессии) — **невозможны** без исправления vault-конфигурации. + +**Файл:** [examples/PG_TEST/postgres_extra.tf](examples/PG_TEST/postgres_extra.tf) + +--- + +### ERR-PG-07: HTTP 408 от IAM API (auth-api-test.ngcloud.ru) + +**Симптом** + +``` +Error: Ошибка клиента + with nubes_postgres_user.pg_test_user + ошибка API 408: {"IAM URL":"https://auth-api-test.ngcloud.ru/api/v1/auth/user", + "idpResponse":{"prefix":{"status_text":"Request Time-out","statuscode":"408 Request Time-out"}}} +``` + +Может проявляться даже на этапе `terraform plan` (refresh инстанса). + +**Причина** + +Транзитная перегрузка тест-IAM-сервиса `auth-api-test.ngcloud.ru`. Возникает +после серии интенсивных apply/destroy в течение одного или нескольких часов. + +**Решение** + +Подождать 5–10 минут и повторить apply. Ошибка проходит самостоятельно. + +**Важно**: в production окружении (`auth-api.ngcloud.ru`) эта проблема +предположительно не воспроизводится. + +--- + ## 2026-03-29 — SSH timeout после destroy VM example ### Симптом diff --git a/doc/pg-terraform-behavior.md b/doc/pg-terraform-behavior.md new file mode 100644 index 0000000..5482813 --- /dev/null +++ b/doc/pg-terraform-behavior.md @@ -0,0 +1,359 @@ +# Отчёт: поведение Nubes PostgreSQL с Terraform + +Дата: 2026-04-01 +Провайдер: `terra.k8c.ru/nubes/nubes` v5.0.51 +API: `https://deck-api-test.ngcloud.ru/api/v1/index.cfm` +Окружение: realm `k8s-3-sandbox-nubes-ru`, PG `pg-test-02` (PostgreSQL 17) +Конфигурация: [`examples/PG_TEST/`](../examples/PG_TEST/) + +--- + +## 1. Создание инстанса (nubes_postgres) + +### 1.1 Первое создание (clean state) + +Работает. Создание выполняется асинхронно — провайдер поллит операцию до `operation_timeout`. + +``` +nubes_postgres.pg_test_instance: Creating... +nubes_postgres.pg_test_instance: Still creating... [00m10s elapsed] +... +nubes_postgres.pg_test_instance: Creation complete after Xm Ys +``` + +Тайминг в тестах не зафиксирован отдельно (инстанс "переиспользовался" между +попытками через `adopt_existing_on_create`). + +### 1.2 adopt_existing_on_create + +Флаг работает: если инстанс с таким `resource_name` уже существует в Nubes — +Terraform принимает его без ошибки и привязывает к state. + +### 1.3 suspend_on_destroy = true (дефолтное поведение) + +При `terraform destroy` инстанс **суспендится**, а не удаляется физически. +Видно из плана при destroy: `suspend_on_destroy = true`. + +### 1.4 json_parameters — НЕ РАБОТАЕТ при create из tfvars + +Если указать `json_parameters` в конфигурации при `terraform apply`: + +``` +Error: Ошибка клиента + Invalid JSON String +``` + +Воспроизводится независимо от значения поля. +**ОДНАКО**: после создания инстанса без `json_parameters` провайдер сам +заполняет его в state (`jsonParameters.log_connections = "off"` и т.д.) — значит +Nubes API ставит дефолты. При следующем apply план показывает `json_parameters` +в `+ resource` блоке (Computed default), но при выполнении apply это не вызывает +ошибку (поле уже применено провайдером через defaults). + +**Вывод**: `json_parameters` в конфиге — не указывать. Nubes сам ставит дефолты. + +### 1.5 vault_secrets — ключевая проблема идемпотентности + +`vault_secrets` — Computed атрибут, заполняется провайдером. Nubes API обновляет +его значение после каждой операции с пользователями (создание/удаление переписывает +Vault Secret с паролями). + +**Проблема**: при любом повторном `terraform apply` Terraform обнаруживает: + +``` +Note: Objects have changed outside of Terraform + # nubes_postgres.pg_test_instance has changed + ~ vault_secrets = (sensitive value) +``` + +Это приводит к плану: +``` + # nubes_postgres.pg_test_instance will be updated in-place + ~ id = "e0e74801-..." -> (known after apply) ← id уходит в unknown! + + # nubes_postgres_user.pg_test_user must be replaced ← потому что postgres_id unknown + # nubes_postgres_database.pg_test_db must be replaced ← аналогично +``` + +Каждый повторный apply = уничтожение и пересоздание всех дочерних ресурсов +(`nubes_postgres_user`, `nubes_postgres_database`). + +**Попытка обхода через `lifecycle { ignore_changes = [vault_secrets] }`**: +Terraform выдаёт предупреждение и игнорирует директиву: +> "Including this attribute in ignore_changes has no effect." + +`vault_secrets` — Computed-only (нет configured value для сравнения), +поэтому `ignore_changes` для него не применим по дизайну Terraform. + +**Статус: открытая проблема.** Обходного пути на уровне конфигурации нет. +Корень — в реализации провайдера: id инстанса уходит в `(known after apply)` +при in-place update, что форсирует replace зависимых ресурсов. + +--- + +## 2. Создание пользователей (nubes_postgres_user) + +### 2.1 Нельзя создавать несколько пользователей одновременно + +Terraform по умолчанию параллельно создаёт независимые ресурсы. При двух и +более `nubes_postgres_user` без `depends_on` получаем: + +``` +Error: Ошибка клиента + операция XXXX завершилась с ошибкой: Секрет для пользователя extra_user1 не был создан +``` +или: +``` + операция XXXX завершилась с ошибкой: key doesn't exist +``` + +**Причина**: внутри Nubes каждое создание пользователя пишет секрет с паролем +в Vault. Конкурентные записи в один Secret вызывают race condition. + +**Решение**: строгий последовательный `depends_on` chain — каждый следующий +ресурс явно ждёт предыдущий, даже если прямых ссылок на атрибуты нет. + +### 2.2 Тайминг создания + +В тестах (декларации после предыдущих операций): + +| Попытка | Время | +|---|---| +| pg_test_user (первая попытка) | ~52–75 сек | +| pg_test_user (повторные попытки) | ~52–83 сек | +| test_extra_user1 (чистый) | ~52–90+ сек | +| test_extra_user1 (с зависшим состоянием) | ~3 мин 10 сек → Error | + +Создание через несколько попыток занимает в среднем **~60–90 секунд**. + +### 2.3 Роль app_user — НЕ РАБОТАЕТ + +```hcl +resource "nubes_postgres_user" "test_app_user" { + role = "app_user" + ... +} +``` + +Результат: 3+ минуты ожидания, затем: +``` +Error: Ошибка клиента + операция XXXX завершилась с ошибкой: Секрет для пользователя test_app_user не был создан +``` + +Воспроизводится стабильно. Роль `ddl_user` работает корректно. + +**Вывод**: для `nubes_postgres_user` рабочая роль — только `ddl_user`. +Роль `app_user` либо не реализована для этого ресурса, либо требует +иного процесса создания. + +### 2.4 adopt_existing_on_create при "зависшем" пользователе + +Если пользователь был частично создан в Nubes (apply упал в середине операции), +то при следующем apply с `adopt_existing_on_create = true`: + +``` +Error: Нарушена консистентность + Операция вернула duplicate/exist, но объект не найден в state_out +``` + +**Провайдер не может принять существующего пользователя если его нет в `state_out` +инстанса**, даже с `adopt_existing_on_create = true`. `state_out` инстанса +обновляется Nubes только при успешном завершении операции — если операция зависла, +`state_out` не обновляется. + +**Решение**: использовать другое имя пользователя (старое имя "замусорено" +в Nubes API до очистки на их стороне). + +### 2.5 Тайминг удаления + +| Ресурс | Время | +|---|---| +| nubes_postgres_user | 56 сек – 1 мин 21 сек | + +### 2.6 Только один пользователь с vault_secrets на инстанс (критическое ограничение) + +**Наблюдение**: в тест-окружении `k8s-3-sandbox-nubes-ru` успешно создаётся +**только первый пользователь** на PG-инстансе. Второй пользователь (`test_eu1`, +`extra_user1` — любое имя) никогда не может получить `vault_secrets`: + +``` +Error: Ошибка клиента + with nubes_postgres_user.test_extra_user1 + операция XXXX завершилась с ошибкой: Секрет для пользователя test_eu1 не был создан +``` + +Поведение: 3–4 минуты ожидания vault, затем ошибка. Воспроизводится 100% случаев +для 5+ попыток с разными именами и разными apply-сессиями. + +**Первый пользователь (pg_test_user)** успешно проходит через adoption за ~1 сек — +его `vault_secrets` был создан при первом apply. Adoption не пересоздаёт vault-запись. + +**Гипотеза**: Vault backend для данного PG-инстанса ограничен одной записью +(`user0`/основной пользователь). Vault policy не предусматривает путей для +дополнительных пользователей. Проблема на стороне конфигурации тест-окружения Nubes. + +**Следствие**: lifecycle-тесты с несколькими пользователями в текущем тест-окружении +**невозможны без исправления vault-конфигурации на стороне Nubes**. + +--- + +## 3. Создание баз данных (nubes_postgres_database) + +### 3.1 Тайминг создания + +| Ресурс | Время | +|---|---| +| nubes_postgres_database | 47 сек – 1 мин 6 сек | + +### 3.2 Тайминг удаления + +| Ресурс | Время | +|---|---| +| nubes_postgres_database | 46 сек – 1 мин 32 сек | + +### 3.3 db_owner должен существовать к моменту создания БД + +`db_owner` задаётся как `string` (имя пользователя). Если пользователь не существует +в Nubes — создание БД падает. Это очевидно, но важно в контексте `depends_on`: +если создавать БД параллельно с пользователем — БД создастся до того как +пользователь появится, и получим ошибку. + +--- + +## 4. Последовательность зависимостей (обязательная) + +Нарушение любого из `depends_on` в цепочке вызывает ошибки API. +Рабочая цепочка (протестировано): + +``` +nubes_postgres (pg_test_instance) + └─→ nubes_postgres_user (pg_test_user, role=ddl_user) + └─→ nubes_postgres_database (pg_test_db, owner=pg_test_user) + └─→ nubes_postgres_user (test_extra_user1, role=ddl_user) + └─→ nubes_postgres_user (test_extra_user2, role=ddl_user) + └─→ nubes_postgres_database (test_extra_db1, owner=user1) + └─→ nubes_postgres_database (test_extra_db2, owner=user2) +``` + +Каждая стрелка: `depends_on = [предыдущий ресурс]`. + +**Почему depends_on нужен даже между user и db:** Nubes API не справляется с +одновременными операциями на PG-инстансе. Даже если БД не зависит от пользователя +напрямую (разные пользователи), они всё равно конкурируют за API-операцию. + +--- + +## 5. Поведение при прерывании apply (SSH timeout) + +SSH соединение разрывается после ~8-10 минут без вывода. +При запуске через `ssh ... "cd ... && terraform apply"` apply убивается вместе +с SSH-процессом. + +**Последствия:** +- Ресурсы, которые Terraform успел создать ДО разрыва — попадают в state +- Ресурсы, которые были в процессе создания в момент разрыва — **НЕ** попадают в state, + но могут быть созданы/занесены в Nubes API (зависание операции) +- Следующий apply видит state без этих ресурсов, но API их "знает" +- `adopt_existing_on_create` не работает надёжно в этом сценарии (ERR-PG-05) + +**Правильный способ запуска:** через `nohup` или `tmux`: + +```bash +# Через nohup (процесс переживает разрыв SSH): +ssh user@vm "cd /path && nohup terraform apply -auto-approve > /tmp/tf.log 2>&1 & echo PID=\$!" + +# Проверить прогресс: +ssh user@vm "tail -20 /tmp/tf.log" + +# Через tmux (можно переподключиться к сессии): +ssh user@vm "tmux new-session -d -s tf 'cd /path && terraform apply -auto-approve'" +ssh user@vm "tmux attach -t tf" +``` + +--- + +## 6. Суммарная таблица поведения + +| Операция | Работает | Проблемы | Решение | +|---|---|---|---| +| Создание инстанса | ✅ | — | — | +| Переиспользование инстанса (`adopt`) | ✅ | — | — | +| Suspend при destroy | ✅ (это дефолт) | — | — | +| `json_parameters` в конфиге | ❌ | Invalid JSON String | Не указывать, Nubes ставит дефолты | +| Создание `nubes_postgres_user` с `ddl_user` | ✅ | ~60–90 сек | — | +| Создание `nubes_postgres_user` с `app_user` | ❌ | Секрет не создан (~3 мин) | Только `ddl_user` | +| Параллельное создание нескольких users | ❌ | Race condition в Vault | `depends_on` chain | +| Создание 2-го пользователя (любого) | ❌ | Vault: Секрет не создан (~3–4 мин) | Ограничение тест-окружения | +| Удаление `nubes_postgres_user` | ✅ | ~56–81 сек | — | +| Принятие существующего user (`adopt`) | ✅ | не работает при "зависшей" операции | Новое имя | +| Создание `nubes_postgres_database` | ✅ | ~47–66 сек | — | +| Удаление `nubes_postgres_database` | ✅ | ~46–92 сек | — | +| Повторный apply (idempotent) | ❌ частично | `vault_secrets` → destroy+recreate user/db | Открытая проблема | +| apply через SSH (долгий) | ❌ | SSH timeout убивает процесс | `nohup` или `tmux` | + +--- + +## 7. Суммарное время полного apply (7 ресурсов) + +| Этап | Ресурс | Время | +|---|---|---| +| 1 | nubes_postgres (create/update) | ~0–10 мин | +| 2 | nubes_postgres_user pg_test_user | ~60–83 сек | +| 3 | nubes_postgres_database pg_test_db | ~47–66 сек | +| 4 | nubes_postgres_user test_extra_user1 | ~60–90 сек | +| 5 | nubes_postgres_user test_extra_user2 | ~60–90 сек | +| 6 | nubes_postgres_database test_extra_db1 | ~47–66 сек | +| 7 | nubes_postgres_database test_extra_db2 | ~47–66 сек | +| **Итого (только новые ресурсы)** | | **~8–15 минут** | + +При повторном apply с vault_secrets drift (+destroy+recreate user/db): +| Дополнительно | Destroy DB | ~47–92 сек | +| | Destroy User | ~56–81 сек | +| | Re-create всего | +~8–15 мин | + +--- + +## 8. Рекомендации для работы с nubes PostgreSQL через Terraform + +1. **Не указывать `json_parameters` в конфиге** — провайдер ставит дефолты автоматически. + +2. **Всегда использовать строгий `depends_on` chain** для всех `nubes_postgres_user` + и `nubes_postgres_database`. Параллелизм ломает API. + +3. **Роль пользователей — только `ddl_user`**. `app_user` не работает. + +4. **Запускать apply через `nohup` или `tmux`**, не через прямую SSH-команду. + Полный apply занимает 8–15 минут и SSH таймаутится. + +5. **Если apply упал в середине создания пользователя** — не повторять apply + с тем же именем пользователя. Изменить `username` в конфиге на новое значение. + +6. **Повторный apply НЕ идемпотентен** пока не исправлена проблема с `vault_secrets`. + Каждый apply пересоздаёт пользователей и базы. Это баг провайдера. + +7. **`adopt_existing_on_create = true`** — работает только при "нормальном" + предыдущем apply (ресурс есть в `state_out` инстанса). При засорённых + операциях — не помогает. + +--- + +## 9. Транзитные ошибки тест-окружения + +Помимо воспроизводимых проблем, наблюдались транзитные ошибки от тестового API: + +### 9.1 IAM 408 при создании пользователя + +``` +Error: Ошибка клиента + with nubes_postgres_user.pg_test_user + ошибка API 408: {"IAM URL":"https://auth-api-test.ngcloud.ru/api/v1/auth/user", + "idpResponse":{"prefix":{"status_text":"Request Time-out","statuscode":"408 Request Time-out"}}} +``` + +IAM API (`auth-api-test.ngcloud.ru`) вернул Connection Timeout при создании пользователя. +Транзитная ошибка — при повторном apply операция проходила успешно. + +**Вывод**: тест-окружение (`deck-api-test`, `auth-api-test`) не даёт 100% надёжности. +Для production окружения поведение может отличаться. + diff --git a/doc/progress.md b/doc/progress.md index 81cc12f..48d5ad0 100644 --- a/doc/progress.md +++ b/doc/progress.md @@ -1,6 +1,102 @@ # Прогресс разработки -Последнее обновление: 2026-03-30 +Последнее обновление: 2026-04-01 + +--- + +## 2026-04-01 — PG_TEST: создание и отладка lifecycle-тестов для nubes PostgreSQL + +### Цель + +Создать набор Terraform-манифестов для тестирования провайдера `nubes` (PostgreSQL ресурсы): +создание/удаление/модификация инстансов, пользователей и баз данных через Nubes API. +Передать заказчику как готовый шаблон (достаточно вписать токен и s3_uid). + +### Что создано + +**`examples/PG_TEST/`** — новая директория с полным набором манифестов: + +| Файл | Назначение | +|---|---| +| `main.tf` | провайдер nubes v5.0.51, объявление переменных | +| `postgres.tf` | базовые ресурсы: инстанс, пользователь, база данных | +| `postgres_extra.tf` | дополнительные ресурсы для lifecycle-тестов | +| `outputs.tf` | host, port, user, password (sensitive), DSN (sensitive) | +| `terraform.tfvars` | рабочие значения (не в git) | +| `terraform.tfvars.example` | шаблон для заказчика с masked placeholders | +| `test_lifecycle.sh` | скрипт последовательного lifecycle-тестирования | + +### Что протестировано (итоги) + +#### ✅ Работает + +- Создание `nubes_postgres` инстанса (pg-test-02, realm=k8s-3-sandbox-nubes-ru) +- Создание `nubes_postgres_user` с ролью `ddl_user` +- Создание `nubes_postgres_database` с owner из `nubes_postgres_user` +- `adopt_existing_on_create = true` — корректно работает при первом apply если ресурс уже есть +- `lifecycle { ignore_changes = [vault_secrets] }` — **не эффективно**: `vault_secrets` является Computed-only, директива игнорируется (Terraform warning) +- Строгий `depends_on` chain — устраняет race condition в API (см. ниже) +- Destroy: удаление DB (~47s), User (~56-76s) проходит корректно + +#### ❌ Не работает / Ограничения API + +| Проблема | Описание | Решение | +|---|---|---| +| `json_parameters` | "Invalid JSON String" при любом значении | убран из конфига | +| `role = "app_user"` | "Секрет не был создан" (~3 мин таймаут) | только `ddl_user` | +| Параллельное создание пользователей | Race condition на Vault side | `depends_on` chain | +| `vault_secrets` внешнее изменение | Форсирует destroy+recreate зависимых ресурсов | `ignore_changes` не эффективен (Computed-only), открытая проблема | +| `adopt_existing_on_create` при "stale" state | Ошибка "Нарушена консистентность" | `terraform destroy` + rebuild | + +### Итоговая архитектура depends_on + +``` +nubes_postgres (pg_test_instance) + └─→ nubes_postgres_user (pg_test_user) + └─→ nubes_postgres_database (pg_test_db) + └─→ nubes_postgres_user (test_extra_user1) + └─→ nubes_postgres_user (test_extra_user2) + └─→ nubes_postgres_database (test_extra_db1) + └─→ nubes_postgres_database (test_extra_db2) +``` + +### Ключевые параметры окружения + +- Провайдер: `terra.k8c.ru/nubes/nubes` v5.0.51 +- API endpoint: `https://deck-api-test.ngcloud.ru/api/v1/index.cfm` +- realm: `k8s-3-sandbox-nubes-ru` +- PG инстанс ID: `e0e74801-d68e-4637-8ef3-d846b289846e` (pg-test-02) +- VM для запуска: `naeel@5.172.178.213` (ключ: `secrets/naeel_vm_id_ed25519`) +- Путь на VM: `/home/naeel/terra/sless/examples/PG_TEST` + +### Текущий статус (обновлено 2026-04-01) + +**Финальный итог сессии**: lifecycle-тесты с несколькими пользователями +**невозможны** в текущем тест-окружении Nubes. Vault backend PG-инстанса +`e0e74801` поддерживает только одного пользователя с vault_secrets. + +Подтверждено 5+ попытками с разными именами: +- `extra_user1`, `test_eu1` (ddl_user) — все завершились ERR-PG-06 + +**Достигнуто в сессии:** +- ✅ Один пользователь + одна БД создаются и удаляются корректно +- ✅ Все ошибки задокументированы (ERR-PG-01..ERR-PG-07) +- ✅ Создан подробный отчёт [`doc/pg-terraform-behavior.md`](pg-terraform-behavior.md) +- ✅ Архитектура `depends_on` chain подтверждена и задокументирована +- ❌ Несколько пользователей на одном инстансе — заблокировано Vault-ограничением + +**Требуется от Nubes**: исправить vault policy для PG-инстансов тест-окружения, +чтобы допускать несколько vault_secrets записей на один инстанс. + +Следующие шаги lifecycle-теста: создать всё → удалить user2+db2 → воссоздать → невалидные параметры + +### Подробности ошибок + +→ [doc/errors/log.md](doc/errors/log.md) (ERR-PG-01 … ERR-PG-05) + +### Принятые решения + +→ [doc/decisions/log.md](doc/decisions/log.md) (3 решения: ignore_changes, depends_on chain, только ddl_user) ---