- Определена архитектура managed IoT service - Согласовано решение: RabbitMQ (MVP), потом Kafka; EMQX + CRD контроллер - Создан подробный план для Sonnet (doc/iot-mvp-plan.md) - Добавлено правило в copilot-instructions: лог мышления в doc/thinking/ по датам - Полный ход рассуждений в doc/thinking/2026-04-04.md Ключевые решения: - IoT код в iot/ (легко вынести потом) - CRD IoTDevice + контроллер (как все остальное в sless) - EMQX HTTP Auth Backend для динамической аутентификации устройств - Архитектура broker-agnostic (легко переключить на Kafka) - Terraform: расширяем текущий provider (sless_iot_device ресурс)
194 lines
7.2 KiB
Markdown
194 lines
7.2 KiB
Markdown
# PG_TEST — инфраструктура тестирования Nubes PostgreSQL
|
||
|
||
Создан: 2026-04-01
|
||
|
||
---
|
||
|
||
## Цель
|
||
|
||
Набор Terraform-манифестов для тестирования провайдера `nubes` (ресурсы PostgreSQL).
|
||
Покрывает: создание инстанса, управление пользователями и базами данных, lifecycle-операции.
|
||
|
||
Также используется как шаблон для передачи заказчикам — достаточно вписать
|
||
`api_token`, `s3_uid`, `realm` в `terraform.tfvars`.
|
||
|
||
---
|
||
|
||
## Расположение
|
||
|
||
| Место | Путь |
|
||
|---|---|
|
||
| Локально | `/home/naeel/remote_dev/sless/examples/PG_TEST/` |
|
||
| На VM | `/home/naeel/terra/sless/examples/PG_TEST/` |
|
||
| VM | `naeel@5.172.178.213` |
|
||
| SSH-ключ | `secrets/naeel_vm_id_ed25519` |
|
||
|
||
> **Правило:** все `terraform` команды выполняются только на VM через SSH.
|
||
> Локально — только редактирование файлов + `scp` для синхронизации.
|
||
|
||
---
|
||
|
||
## Файловая структура
|
||
|
||
```
|
||
examples/PG_TEST/
|
||
├── main.tf # провайдер nubes + переменные
|
||
├── postgres.tf # инстанс + базовый пользователь + база
|
||
├── postgres_extra.tf # доп. пользователи и базы для lifecycle-тестов
|
||
├── outputs.tf # host, port, user, password, DSN
|
||
├── terraform.tfvars # рабочие значения (не в git, токен и IDs)
|
||
├── terraform.tfvars.example # шаблон для заказчика (masked placeholders)
|
||
└── test_lifecycle.sh # скрипт последовательного lifecycle-тестирования
|
||
```
|
||
|
||
---
|
||
|
||
## Провайдер
|
||
|
||
```hcl
|
||
terraform {
|
||
required_providers {
|
||
nubes = {
|
||
source = "terra.k8c.ru/nubes/nubes"
|
||
version = "5.0.51"
|
||
}
|
||
}
|
||
}
|
||
|
||
provider "nubes" {
|
||
api_endpoint = "https://deck-api-test.ngcloud.ru/api/v1/index.cfm"
|
||
api_token = var.api_token
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## Ресурсы
|
||
|
||
### nubes_postgres (pg_test_instance)
|
||
|
||
- `resource_name = "pg-test-02"`
|
||
- `resource_realm = "k8s-3-sandbox-nubes-ru"`
|
||
- `app_version = "17"` (PostgreSQL 17)
|
||
- CPU: 500m, Memory: 512 MiB, Disk: 1 GiB
|
||
- `adopt_existing_on_create = true`
|
||
- `operation_timeout = "11m"`
|
||
- **`lifecycle { ignore_changes }`** — не решает проблему с `vault_secrets` (см. ERR-PG-02)
|
||
|
||
Инстанс ID: `e0e74801-d68e-4637-8ef3-d846b289846e`
|
||
|
||
### nubes_postgres_user
|
||
|
||
- Рабочая роль: **только `ddl_user`** (роль `app_user` не работает — ERR-PG-04)
|
||
- `adopt_existing_on_create = true`
|
||
- Пользователи создаются **строго последовательно** через `depends_on` (ERR-PG-03)
|
||
|
||
### nubes_postgres_database
|
||
|
||
- `adopt_existing_on_create = true`
|
||
- `db_owner` = username из `nubes_postgres_user`
|
||
- Создаётся после всех пользователей которые будут db_owner (через `depends_on`)
|
||
|
||
---
|
||
|
||
## Обязательная цепочка depends_on
|
||
|
||
Nubes API не поддерживает параллельные операции на одном PG инстансе.
|
||
Нарушение вызывает race condition в Vault (ERR-PG-03).
|
||
|
||
```
|
||
nubes_postgres
|
||
└─→ pg_test_user (ddl_user)
|
||
└─→ pg_test_db (owner=pg_test_user)
|
||
└─→ test_extra_user1 (ddl_user)
|
||
└─→ test_extra_user2 (ddl_user)
|
||
└─→ test_extra_db1 (owner=extra_user1)
|
||
└─→ test_extra_db2 (owner=extra_user2)
|
||
```
|
||
|
||
---
|
||
|
||
## Переменные (terraform.tfvars)
|
||
|
||
| Переменная | Описание | Пример |
|
||
|---|---|---|
|
||
| `api_token` | JWT токен Nubes API | `eyJ...` |
|
||
| `s3_uid` | UUID S3 bucket для бэкапов PG | `332cdb0d-...` |
|
||
| `realm` | realm кластера | `k8s-3-sandbox-nubes-ru` |
|
||
| `pg_resource_name` | имя PG инстанса | `pg-test-02` |
|
||
| `pg_username` | имя основного пользователя | `user0` |
|
||
| `pg_db_name` | имя основной базы данных | `db0` |
|
||
| `pg_role` | роль основного пользователя | `ddl_user` |
|
||
|
||
---
|
||
|
||
## Команды
|
||
|
||
Все команды — через SSH на VM:
|
||
|
||
```bash
|
||
SSH="ssh -i /home/naeel/remote_dev/sless/secrets/naeel_vm_id_ed25519 -o StrictHostKeyChecking=no naeel@5.172.178.213"
|
||
TF="cd /home/naeel/terra/sless/examples/PG_TEST &&"
|
||
|
||
# Применить конфигурацию
|
||
$SSH "$TF terraform apply -auto-approve"
|
||
|
||
# Проверить state
|
||
$SSH "$TF terraform state list"
|
||
|
||
# Посмотреть outputs
|
||
$SSH "$TF terraform output"
|
||
|
||
# Удалить все ресурсы
|
||
$SSH "$TF terraform destroy -auto-approve"
|
||
```
|
||
|
||
Синхронизация файлов на VM:
|
||
|
||
```bash
|
||
scp -i secrets/naeel_vm_id_ed25519 examples/PG_TEST/postgres.tf \
|
||
naeel@5.172.178.213:/home/naeel/terra/sless/examples/PG_TEST/postgres.tf
|
||
```
|
||
|
||
---
|
||
|
||
## Известные ограничения API
|
||
|
||
| # | Проблема | Статус |
|
||
|---|---|---|
|
||
| ERR-PG-01 | `json_parameters` — "Invalid JSON String" | обойдено: убран параметр |
|
||
| ERR-PG-02 | `vault_secrets` обновляется вне TF | открытая проблема: `ignore_changes` не эффективен |
|
||
| ERR-PG-03 | Race condition при параллельном создании users | обойдено: `depends_on` chain |
|
||
| ERR-PG-04 | Роль `app_user` — "Секрет не был создан" | не работает, используем только `ddl_user` |
|
||
| ERR-PG-05 | "Нарушена консистентность" при stale state | решение: `terraform destroy` + rebuild |
|
||
|
||
Подробности: [doc/errors/log.md](doc/errors/log.md)
|
||
|
||
---
|
||
|
||
## Ожидаемые времена операций
|
||
|
||
| Операция | Примерное время |
|
||
|---|---|
|
||
| Создание `nubes_postgres_user` | ~50–75 секунд |
|
||
| Удаление `nubes_postgres_user` | ~56–76 секунд |
|
||
| Создание `nubes_postgres_database` | ~47–70 секунд |
|
||
| Удаление `nubes_postgres_database` | ~46–92 секунды |
|
||
| Обновление `nubes_postgres` in-place | мгновенно (~0s) |
|
||
|
||
Полный `apply` с 6 новыми ресурсами занимает **~8–12 минут**.
|
||
|
||
---
|
||
|
||
## Lifecycle-тест (test_lifecycle.sh)
|
||
|
||
Скрипт тестирует последовательность операций:
|
||
|
||
1. **Создать всё** — apply базовой конфигурации + extra
|
||
2. **Удалить user2 + db2** — закомментировать ресурсы, apply
|
||
3. **Воссоздать** — раскомментировать, apply
|
||
4. **Сменить db_owner** — extra_db1.owner: extra_user1 → extra_user2
|
||
5. **Невалидные параметры** — db_owner = несуществующий пользователь (ожидать ошибку API)
|
||
|
||
Запуск: `$SSH "cd /home/naeel/terra/sless/examples/PG_TEST && bash test_lifecycle.sh"`
|