docs(arch): принцип секретов подресурсов — в TOOLS/ARCHITECTURE.md
Записал в ОБЩИЙ файл архитектуры (TOOLS/ARCHITECTURE.md, PRIMARY SOURCE OF TRUTH): - раздел «Subresource-born secrets» в Subresource Resources — проблема, принцип, правило «service-specific DATA, never logic», факт postgres vs mariadb; - пункт 3 в Exception Registry — как объявлять признак в YAML-спеке и прокидывать через types.go + loader.go, без svc.Name == "..." в шаблоне. В provider_philosophy.md оставлена короткая ссылка на ARCHITECTURE.md (источник один).
This commit is contained in:
@@ -203,6 +203,30 @@ resource "nubes_postgres_user" "user1" {
|
|||||||
role = "app_user"
|
role = "app_user"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#### Subresource-born secrets (principle)
|
||||||
|
|
||||||
|
Some `create_user` operations generate a password on the platform side and store it
|
||||||
|
in the PARENT instance's `vault_secrets`; the subresource's `Create` does not read it
|
||||||
|
back, and the parent's `vault_secrets` (Computed) refreshes only on `Read`. Result: in a
|
||||||
|
single `apply`, the password is unavailable right after `create_user` (accessing
|
||||||
|
`vault_secrets["users"]` fails with `Invalid index`).
|
||||||
|
|
||||||
|
**Principle:** a secret born in a subresource operation must become an OUTPUT of that
|
||||||
|
subresource at the end of its `Create`; consumers read `nubes_<svc>_<sub>.<password>`,
|
||||||
|
never the parent's `vault_secrets`.
|
||||||
|
|
||||||
|
**Rule:** this is service-specific DATA, never logic (see Exception Registry below):
|
||||||
|
the flag «user password is platform-generated, decrypt from parent vault, secret name X»
|
||||||
|
comes from the service YAML spec, exactly like `suspend_on_destroy_default`. The shared
|
||||||
|
subresource template (`TOOLS/resource-generator/internal/templates/subresource.go`) only
|
||||||
|
adds a conditional block gated on that flag — no service name is hardcoded there.
|
||||||
|
|
||||||
|
Per-service fact (from specs):
|
||||||
|
- PostgreSQL (`90_postgres.yaml`): `create_user` has NO `password` input → password is
|
||||||
|
platform-generated into `vault_secrets["users"]` → NEEDS the output.
|
||||||
|
- MariaDB (`115_mariadb.yaml`): `create_user` TAKES `password` as input (sensitive) →
|
||||||
|
the password is already in the manifest (`nubes_mariadb_user.x.password`) → output NOT needed.
|
||||||
|
|
||||||
### Redeploy (inline action)
|
### Redeploy (inline action)
|
||||||
|
|
||||||
Services with `redeploy` operation get a `git_revision` field in the main resource.
|
Services with `redeploy` operation get a `git_revision` field in the main resource.
|
||||||
@@ -292,6 +316,13 @@ services. Service-specific deviations are of two kinds:
|
|||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `serviceSpecificDocExamples` | `TOOLS/docs-generator/internal/writers/writers.go` | per-service doc examples, gated on service name + required state/vault keys |
|
| `serviceSpecificDocExamples` | `TOOLS/docs-generator/internal/writers/writers.go` | per-service doc examples, gated on service name + required state/vault keys |
|
||||||
|
|
||||||
|
3. **Subresource-born secrets** — a platform-generated user password available only after
|
||||||
|
`create_user` (see «Subresource-born secrets» under «Subresource Resources»). The
|
||||||
|
generator flag «user password is platform-generated; read from parent vault secret X»
|
||||||
|
is declared in the service YAML spec — add the field to the spec's struct in
|
||||||
|
`TOOLS/resource-generator/internal/types/types.go` and wire it in
|
||||||
|
`TOOLS/resource-generator/internal/loader/loader.go`, NOT as `svc.Name == "..."` logic.
|
||||||
|
|
||||||
Rules:
|
Rules:
|
||||||
|
|
||||||
- Key by stable service NAME (slug), never by raw numeric ID.
|
- Key by stable service NAME (slug), never by raw numeric ID.
|
||||||
|
|||||||
@@ -48,41 +48,8 @@ To prevent "bad applies" and incomplete infrastructure states, the provider will
|
|||||||
- Изменение ключевых параметров подресурса => ресурс заменяется.
|
- Изменение ключевых параметров подресурса => ресурс заменяется.
|
||||||
- Это соответствует возможностям API и сохраняет корректность состояния Terraform.
|
- Это соответствует возможностям API и сохраняет корректность состояния Terraform.
|
||||||
|
|
||||||
### Секреты, рождаемые операцией подресурса (принцип и практика)
|
> Секреты, рождаемые операцией подресурса (пароль пользователя, авто-генерируемый
|
||||||
|
> в `create_user`), описаны в `TOOLS/ARCHITECTURE.md` → «Subresource-born secrets».
|
||||||
**Проблема (наблюдаемая, 2026-10-01):** у части сервисов секрет (пароль пользователя
|
|
||||||
БД) **генерируется платформой** внутри операции `create_user`, а доступен он не в
|
|
||||||
выходе подресурса, а в `vault_secrets` **родительского инстанса**. При этом
|
|
||||||
`vault_secrets` родителя — `Computed`-атрибут, который обновляется только в `Read`
|
|
||||||
родителя (перечитывание облака на refresh/повторном apply), а **не** в конце
|
|
||||||
`Create` подресурса. Следствие: внутри одного `apply` после `create_user` пароль
|
|
||||||
нельзя прочитать — `vault_secrets["users"]` ещё пуст, и обращение к нему даёт
|
|
||||||
`Invalid index`.
|
|
||||||
|
|
||||||
**Принцип (правило для генератора):** секрет, который порождает операция
|
|
||||||
подресурса, должен становиться **выходом самого подресурса** сразу по завершении
|
|
||||||
его `Create`, а не читаться потребителем из родителя. Потребитель берёт пароль
|
|
||||||
из `nubes_<svc>_<sub>.<sub>.password`, и зависимость по графу Терраформа
|
|
||||||
автоматически разносит создание по времени.
|
|
||||||
|
|
||||||
**Как это «прописано для postgres», а не хардкод в шаблоне.** В общий шаблон
|
|
||||||
подресурса (`TOOLS/resource-generator/internal/templates/subresource.go`) НЕ
|
|
||||||
зашивается имя сервиса. Признак «у этого подресурса-пользователя пароль
|
|
||||||
генерируется платформой» должен приходить из **данных спека** (YAML), как уже
|
|
||||||
сделано для `suspend_on_destroy_default` / `adopt_existing_on_create_default`
|
|
||||||
(раздел 7). В шаблоне появится условный блок, срабатывающий только при наличии
|
|
||||||
этого признака.
|
|
||||||
|
|
||||||
**Различия сервисов (факт из спеков):**
|
|
||||||
|
|
||||||
| Сервис | Пароль пользователя | Что нужно |
|
|
||||||
|---|---|---|
|
|
||||||
| PostgreSQL (90) | генерирует платформа → `vault_secrets["users"]` | выход пароля у `postgres_user` из Vault по завершении `create_user` |
|
|
||||||
| MariaDB (115) | задаёт САМ пользователь (входной параметр `password` в `create_user`) | ничего — пароль уже в манифесте, `nubes_mariadb_user.x.password` |
|
|
||||||
|
|
||||||
Вывод: фича «выход пароля» нужна только подресурсам, у которых `create_user`
|
|
||||||
**не** принимает пароль на входе (то есть где он auto-generated). Хардкодить
|
|
||||||
перечень сервисов в шаблоне запрещено — признак декларируется в YAML-спеке сервиса.
|
|
||||||
|
|
||||||
## 7. Каноничная lifecycle-логика для сервисов с suspend/resume
|
## 7. Каноничная lifecycle-логика для сервисов с suspend/resume
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user