README читает человек впервые — ему нужны структура, шаги запуска и операции,
а не разбор прошлых костылей. Удалено:
- раздел «Почему нельзя создать всё одним apply» с историей про try() и PGPASSWORD;
- упоминания try() в apps/lucee.tf, apps/flask.tf, apps/nodejs.tf;
- «data-source/backend» из apps/locals.tf и путь к удалённому разделу из pg/outputs.tf.
Заодно удалён старый TEST_STAND/CRUD/terraform.tfvars (не читается, значения
перенесены в pg/terraform.tfvars и apps/terraform.tfvars).
Проверено: terraform validate — Success в pg/ и apps/ (apps — с временным creds.json).
Было: одна папка, один state — destroy убивал и БД, и приложения; пароль БД
приходилось вытаскивать костылём try() в одном apply, приложения поднимались
с пустым PGPASSWORD.
Стало:
- pg/ — кластер PostgreSQL + пользователь + база + outputs (хост/порт/юзер/база/пароль);
destroy здесь переводит кластер в Suspend, а пользователь и база не удаляются
(keep_on_destroy = true + adopt_existing_on_create = true);
- apps/ — три приложения-потребителя; креды БД читаются из creds.json (выгрузка
outputs папки pg/, т.к. state раздельные, а data-source у провайдера нет);
try() убран полностью — пароль к моменту этого apply уже существует;
- apps/.gitignore — creds.json, terraform.tfvars, state/lock;
- README.md переписан: структура, «зачем разделено», пошаговые 3 шага запуска,
повседневные операции (destroy приложений не трогает БД), про destroy базы.
Проверено: terraform init+validate в обеих папках — Success;
plan в pg/ — 3 to add (кластер, пользователь, база) + 6 outputs.
Инстанс PG при destroy уходит в Suspend (suspend_on_destroy_default: true в
90_postgres.yaml), а не удаляется. Без keep_on_destroy подресурсы (create_user/
create_database) удалялись бы из живого кластера — после resume приложения
работали бы с пустой БД, данные базы были бы потеряны.
keep_on_destroy=true → режим state_only: при destroy подресурс остаётся в облаке
и только убирается из state. В паре с adopt_existing_on_create=true следующий
apply усыновляет существующий объект, а не падает на 'уже существует'.
Проверено: terraform validate — Success (провайдером 3.0.0, где атрибут есть).
Раньше locals читали пароль напрямую: jsondecode(vault_secrets["users"]).user4crudpg.password.
При первом apply пароля ещё нет (create_user выполняется после создания кластера), поэтому
Terraform падал с «Invalid index ... does not identify an element in this collection value».
Теперь через try(... = ""): на первом apply в env идёт пустая строка и прогон не роняет;
на втором apply пароль уже в Vault, try возвращает настоящее значение, приложения получают верный env.
Комментарии в lucee.tf/flask.tf/nodejs.tf объясняют зачем try и почему два apply.
Проверено: terraform validate — Success; plan — No changes; Exit 0.
Провайдер отправляет postgres_conf на платформу как есть (resources_core.FormatString
возвращает строку без перевода имён), поэтому ключи обязаны совпадать со спекой:
postgresConf.paramName / postgresConf.paramValue. С snake_case (param_name/param_value)
платформа падала с "Invalid JSON String" (операция 5AAF1E39-8812-4994-AD14-78D51ED2077D).
Значение paramValue взято '' — как в HAR/pgmodify.har и в TEST_STAND/PG/resources.tf.
План проходит: 6 to add, exit 0.
realm — не секрет, но из-за sensitive = true в plan вместо имени печаталось
"(sensitive value)". Теперь видно resource_realm = "k8s-3-sandbox-nubes-ru".
Плана это не меняло: plan по-прежнему 6 to add, exit 0.
Прочие sensitive оставлены как есть: api_token (секрет), vault_secrets (платформа).
Легаси-версии (5.0.x/5.1.x/3.1.x/2.1.x) в реестре отсутствуют (404), стенды не могли
пройти terraform init. Приведены к новой схеме нумерации от 2026-09-03.
- DEV (nubes-dev): CRUD, POSTGRES, SHTURVAL_MGMT -> 2.0.0
- TEST (nubes-test): CRUD, PG, POSTGRES, MARIA_DB, buck0, kuber, IOT_RMQ_DEMO -> 3.0.0
(DEV_STAND/IOT_KAFKA_DEMO тоже nubes-test -> 3.0.0)
- PROD (nubes): PG1, POSTGRES, RABBIT -> 1.0.0
- README стендов TEST_STAND/buck0, TEST_STAND/PG: версии приведены к 3.0.0
- getting-started: убрана versioned-ссылка на доки (2.1.7) -> актуальный домен без версии
- .gitignore: откатано правило TMP/ (на remote TMP/init-test-*/main.tf трекаются)