diff --git a/TEST_STAND/CRUD/README.md b/TEST_STAND/CRUD/README.md index 86653ad..9b7b205 100644 --- a/TEST_STAND/CRUD/README.md +++ b/TEST_STAND/CRUD/README.md @@ -9,6 +9,27 @@ CRUD = Create / Read / Update / Delete — создать, прочитать, --- +## Где взять манифесты + +Каталог примера — `TEST_STAND/CRUD` в репозитории провайдера. Клонируйте и перейдите в него: + +```bash +git clone https://gitea.services.ngcloud.ru/terraform/tf_provider.git +cd tf_provider/TEST_STAND/CRUD +``` + +Нужен установленный Terraform: + +```bash +terraform version +``` + +Провайдер берётся из реестра — источник и версия заданы в `pg/main.tf` и `apps/main.tf` +(test-стенд: `tf-registry.containerk8s.services.ngcloud.ru/nubes-test/nubes`, версия `3.0.0`). +Дальше все команды выполняются из каталога `TEST_STAND/CRUD`. + +--- + ## Как это устроено Два каталога — два отдельных файла состояния Terraform: @@ -50,7 +71,7 @@ cd ../apps && cp terraform.tfvars.example terraform.tfvars | `pg_resource_name` (кластер) | `pg/terraform.tfvars` | уникально **в пределах стенда** | | `pg_username`, `pg_db_name` | `pg/terraform.tfvars` | уникальны в пределах кластера; служебные имена (`admin`, `postgres`, `standby`) платформа не примет | | `lucee_resource_name`, `flask_resource_name`, `nodejs_resource_name` | `apps/locals.tf` | уникальны **в пределах стенда** | -| `lucee_domain`, `flask_domain`, `nodejs_domain` | `apps/locals.tf` | здесь задаётся **не полный домен, а имя** — суффикс платформа добавляет сама: `lucee-crud` → `lucee-crud.luceek8s.dev.nubes.ru`, `flask-crud` → `flask-crud.pythonk8s.dev.nubes.ru`, `nodejs-crud` → `nodejs-crud.<суффикс>.dev.nubes.ru`. Полные имена уникальны (это обычные DNS-имена), поэтому и задаваемое имя должно быть уникальным | +| `lucee_domain`, `flask_domain`, `nodejs_domain` | `apps/locals.tf` | здесь задаётся **не полный домен, а имя** — суффикс платформа добавляет сама: `lucee-crud` → `lucee-crud.luceek8s.dev.nubes.ru`, `flask-crud` → `flask-crud.pythonk8s.dev.nubes.ru`, `nodejs-crud` → `nodejs-crud.nodejsk8s.dev.nubes.ru`. Полные имена уникальны (это обычные DNS-имена), поэтому и задаваемое имя должно быть уникальным | Почему это важно: все ресурсы создаются с `adopt_existing_on_create = true`, а провайдер ищет инстанс **по имени внутри своего сервиса** (`provider/internal/resources_core/crud.go:171`, @@ -85,7 +106,7 @@ cd ../apps && cp terraform.tfvars.example terraform.tfvars --- -## Запуск — три шага +## Запуск — четыре шага ### 1. База данных (`pg/`) @@ -128,8 +149,27 @@ terraform apply Создадутся три приложения, подключённые к общей БД. -Обязательные значения — `api_token` и `realm` (те же, что в `pg/`). Имена доменов нужно -придумать самому, они должны быть уникальны в облаке — см. раздел «Что пользователь задаёт сам». +Обязательные значения — `api_token` и `realm` (те же, что в `pg/`). Имена доменов и имена +ресурсов приложений задаются в `apps/locals.tf` — см. раздел «Что пользователь задаёт сам». + +### 4. Проверить + +Откройте в браузере три адреса (это полные домены, которые платформа построила из имён в +`apps/locals.tf`): + +| Приложение | Адрес | +|---|---| +| Lucee | | +| Flask | | +| Node.js | | + +Свои адреса можно посмотреть в state: + +```bash +grep -o 'https://[a-z0-9.-]*\.dev\.nubes\.ru' apps/terraform.tfstate | sort -u +``` + +Добавьте запись в одном приложении — она появится в двух других (таблица `crud_items` общая). --- @@ -147,6 +187,21 @@ terraform apply --- +## Если `apply` упал + +Текст ошибки в поле `errorLog` у платформы **не всегда отражает суть** — реальная причина видна +в журнале операции: + +```bash +GET {api_endpoint}/instanceOperations/?fields=cfsParams,errorLog,stages +``` + +`stages[].stageMsg` — массив пар `[заголовок, лог]`, смотреть последнюю запись; `cfsParams` — +фактический набор параметров, ушедший на платформу. Разбор реального случая: +`HISTORY/60_stands/2026-10-01_test_crud_pg_create_failure.md`. + +--- + ## Файлы | Файл | Что делает | @@ -158,6 +213,7 @@ terraform apply | `apps/main.tf` | провайдер, переменные приложений | | `apps/locals.tf` | чтение `creds.json`, домены, версии, размеры | | `apps/lucee.tf`, `apps/flask.tf`, `apps/nodejs.tf` | три приложения | +| `pg/terraform.tfvars.example`, `apps/terraform.tfvars.example` | шаблоны для копирования в `terraform.tfvars` | | `apps/creds.json` | генерируется шагом 2, **не в git** | --- diff --git a/docs/curated/crud/three_apps.md b/docs/curated/crud/three_apps.md index f71ff2e..9290b94 100644 --- a/docs/curated/crud/three_apps.md +++ b/docs/curated/crud/three_apps.md @@ -4,9 +4,27 @@ (Lucee/CFML, Python, Node.js) и одна таблица `crud_items`. Запись, добавленная в любом из трёх приложений, видна в двух других. -Манифесты: `TEST_STAND/CRUD/` (test-стенд) — два каталога: `pg/` (база) и `apps/` (приложения). +Манифесты: `TEST_STAND/CRUD/` в репозитории провайдера — два каталога: `pg/` (база) и `apps/` (приложения). `DEV_STAND/CRUD/` — тот же пример, но по старой схеме: всё в одной папке. +## Где взять манифесты + +Клонируйте репозиторий провайдера и перейдите в каталог примера: + +```bash +git clone https://gitea.services.ngcloud.ru/terraform/tf_provider.git +cd tf_provider/TEST_STAND/CRUD +``` + +Нужен установленный Terraform: + +```bash +terraform version +``` + +Провайдер берётся из реестра — источник и версия заданы в `pg/main.tf` и `apps/main.tf`. +Дальше все команды выполняются из каталога `TEST_STAND/CRUD`. + ## Что создаётся | Ресурс | Имя (по умолчанию) | Что это | @@ -76,7 +94,7 @@ cd ../apps && cp terraform.tfvars.example terraform.tfvars | `pg_resource_name` (кластер) | `pg/terraform.tfvars` | уникально **в пределах стенда** | | `pg_username`, `pg_db_name` | `pg/terraform.tfvars` | уникальны в пределах кластера; служебные имена (`admin`, `postgres`, `standby`) платформа не примет | | `lucee_resource_name`, `flask_resource_name`, `nodejs_resource_name` | `apps/locals.tf` | уникальны **в пределах стенда** | -| `lucee_domain`, `flask_domain`, `nodejs_domain` | `apps/locals.tf` | здесь задаётся **не полный домен, а имя** — суффикс платформа добавляет сама: `lucee-crud` → `lucee-crud.luceek8s.dev.nubes.ru`, `flask-crud` → `flask-crud.pythonk8s.dev.nubes.ru`, `nodejs-crud` → `nodejs-crud.<суффикс>.dev.nubes.ru`. Полные имена уникальны (это обычные DNS-имена), поэтому и задаваемое имя должно быть уникальным | +| `lucee_domain`, `flask_domain`, `nodejs_domain` | `apps/locals.tf` | здесь задаётся **не полный домен, а имя** — суффикс платформа добавляет сама: `lucee-crud` → `lucee-crud.luceek8s.dev.nubes.ru`, `flask-crud` → `flask-crud.pythonk8s.dev.nubes.ru`, `nodejs-crud` → `nodejs-crud.nodejsk8s.dev.nubes.ru`. Полные имена уникальны (это обычные DNS-имена), поэтому и задаваемое имя должно быть уникальным | Почему это важно: все ресурсы создаются с `adopt_existing_on_create = true`, а провайдер ищет инстанс **по имени внутри своего сервиса** (`provider/internal/resources_core/crud.go:171`, @@ -113,7 +131,7 @@ provider "nubes" { } ``` -## Запуск — три шага +## Запуск — четыре шага ### 1. База данных (`pg/`) @@ -153,8 +171,27 @@ terraform apply Создадутся три приложения, подключённые к общей БД. -Обязательные значения — `api_token` и `realm` (те же, что в `pg/`). Имена доменов нужно -придумать самому, они должны быть уникальны в облаке — см. раздел «Что пользователь задаёт сам». +Обязательные значения — `api_token` и `realm` (те же, что в `pg/`). Имена доменов и имена +ресурсов приложений задаются в `apps/locals.tf` — см. раздел «Что пользователь задаёт сам». + +### 4. Проверить + +Откройте в браузере три адреса (это полные домены, которые платформа построила из имён в +`apps/locals.tf`): + +| Приложение | Адрес | +|---|---| +| Lucee | | +| Flask | | +| Node.js | | + +Свои адреса можно посмотреть в state: + +```bash +grep -o 'https://[a-z0-9.-]*\.dev\.nubes\.ru' apps/terraform.tfstate | sort -u +``` + +Добавьте запись в одном приложении — она появится в двух других (таблица `crud_items` общая). ## Справка: выходные параметры `pg/`