doc: pg-terraform behavior report + ERR-PG-06/07

- 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
This commit is contained in:
Repinoid
2026-04-01 19:21:37 +04:00
parent 211563a87c
commit ebbba66146
3 changed files with 700 additions and 1 deletions
+244
View File
@@ -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
### Симптом
+359
View File
@@ -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 (чистый) | ~5290+ сек |
| test_extra_user1 (с зависшим состоянием) | ~3 мин 10 сек → Error |
Создание через несколько попыток занимает в среднем **~6090 секунд**.
### 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` | ✅ | ~6090 сек | — |
| Создание `nubes_postgres_user` с `app_user` | ❌ | Секрет не создан (~3 мин) | Только `ddl_user` |
| Параллельное создание нескольких users | ❌ | Race condition в Vault | `depends_on` chain |
| Создание 2-го пользователя (любого) | ❌ | Vault: Секрет не создан (~3–4 мин) | Ограничение тест-окружения |
| Удаление `nubes_postgres_user` | ✅ | ~5681 сек | — |
| Принятие существующего user (`adopt`) | ✅ | не работает при "зависшей" операции | Новое имя |
| Создание `nubes_postgres_database` | ✅ | ~4766 сек | — |
| Удаление `nubes_postgres_database` | ✅ | ~4692 сек | — |
| Повторный apply (idempotent) | ❌ частично | `vault_secrets` → destroy+recreate user/db | Открытая проблема |
| apply через SSH (долгий) | ❌ | SSH timeout убивает процесс | `nohup` или `tmux` |
---
## 7. Суммарное время полного apply (7 ресурсов)
| Этап | Ресурс | Время |
|---|---|---|
| 1 | nubes_postgres (create/update) | ~010 мин |
| 2 | nubes_postgres_user pg_test_user | ~6083 сек |
| 3 | nubes_postgres_database pg_test_db | ~4766 сек |
| 4 | nubes_postgres_user test_extra_user1 | ~6090 сек |
| 5 | nubes_postgres_user test_extra_user2 | ~6090 сек |
| 6 | nubes_postgres_database test_extra_db1 | ~4766 сек |
| 7 | nubes_postgres_database test_extra_db2 | ~4766 сек |
| **Итого (только новые ресурсы)** | | **~815 минут** |
При повторном apply с vault_secrets drift (+destroy+recreate user/db):
| Дополнительно | Destroy DB | ~4792 сек |
| | Destroy User | ~5681 сек |
| | Re-create всего | +~815 мин |
---
## 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 окружения поведение может отличаться.
+97 -1
View File
@@ -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)
---