fix: curated PG example — use S3 name not UUID, comment every parameter
This commit is contained in:
@@ -1,51 +0,0 @@
|
|||||||
# Баг: DEV postgres Script26 не знает resourceRealm
|
|
||||||
|
|
||||||
Дата: 2026-08-09
|
|
||||||
|
|
||||||
## Симптом
|
|
||||||
|
|
||||||
`terraform apply` на DEV стенде падает с ошибкой:
|
|
||||||
|
|
||||||
```
|
|
||||||
nubes_postgres.npg: операция ... завершилась с ошибкой:
|
|
||||||
No such property: resourceRealm for class: Script26
|
|
||||||
```
|
|
||||||
|
|
||||||
## Причина
|
|
||||||
|
|
||||||
DEV API (`lk-api-gateway-dev.ngcloud.ru`) возвращает `resourceRealm` в метаданных
|
|
||||||
сервиса postgres (ID 90, операция create, параметр startupConfiguration).
|
|
||||||
Но бэкенд-скрипт `Script26`, который фактически выполняет создание Postgres на DEV,
|
|
||||||
**не имеет** свойства `resourceRealm`.
|
|
||||||
|
|
||||||
TEST стенд работает нормально — его скрипт `resourceRealm` принимает.
|
|
||||||
|
|
||||||
## Доказательства
|
|
||||||
|
|
||||||
1. Оба API (DEV и TEST) возвращают одинаковые метаданные — `resourceRealm` присутствует:
|
|
||||||
```
|
|
||||||
generated/dev/resources_yaml/90_postgres.yaml — 2 occurrences
|
|
||||||
generated/test/resources_yaml/90_postgres.yaml — 2 occurrences
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Провайдер собран **из DEV API** (не перепутан с TEST):
|
|
||||||
- YAML сгенерированы: `./TOOLS/scripts/01_generate_yamls.sh --profile TOOLS/config/dev`
|
|
||||||
- Go сгенерирован: `./TOOLS/scripts/02_generate_resources_and_docs_v2.sh --profile TOOLS/config/dev`
|
|
||||||
- Версия: `3.0.2`, Namespace: `nubes-dev`
|
|
||||||
|
|
||||||
3. Terraform-конфиг (DEV_STAND/PGwNewRegistry):
|
|
||||||
```hcl
|
|
||||||
provider "nubes" {
|
|
||||||
api_endpoint = "https://lk-api-gateway-dev.ngcloud.ru/api/v1/svc"
|
|
||||||
}
|
|
||||||
resource "nubes_postgres" "npg" {
|
|
||||||
startup_configuration = {
|
|
||||||
resource_realm = "k8s-3-sandbox-nubes-ru"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Что нужно сделать
|
|
||||||
|
|
||||||
Добавить свойство `resourceRealm` в скрипт `Script26` (DEV postgres create).
|
|
||||||
Привести DEV-скрипт в соответствие с метаданными API (как на TEST).
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
terraform {
|
|
||||||
required_providers {
|
|
||||||
nubes = {
|
|
||||||
source = "tf-registry.containerk8s.services.ngcloud.ru/nubes-test/nubes"
|
|
||||||
version = "5.0.1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "api_token" {
|
|
||||||
type = string
|
|
||||||
sensitive = true
|
|
||||||
description = "Nubes API token"
|
|
||||||
}
|
|
||||||
variable "s3_uid" {
|
|
||||||
type = string
|
|
||||||
sensitive = true
|
|
||||||
description = "Nubes S3 UID"
|
|
||||||
}
|
|
||||||
variable "realm" {
|
|
||||||
type = string
|
|
||||||
sensitive = true
|
|
||||||
description = "resource_realm parameter for nubes_postgres resource"
|
|
||||||
}
|
|
||||||
variable "s3_user_uid" {
|
|
||||||
type = string
|
|
||||||
description = "S3 user UUID"
|
|
||||||
}
|
|
||||||
|
|
||||||
provider "nubes" {
|
|
||||||
api_token = var.api_token
|
|
||||||
api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc"
|
|
||||||
# log_level = "debug" # none | info | debug, default = "none"
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
resource "nubes_postgres" "npg" {
|
|
||||||
resource_name = "pgdev02"
|
|
||||||
|
|
||||||
startup_configuration = {
|
|
||||||
resource_realm = var.realm
|
|
||||||
}
|
|
||||||
|
|
||||||
cluster_configuration = {
|
|
||||||
cpu = 500
|
|
||||||
memory = 512
|
|
||||||
replicas = 1
|
|
||||||
disk = 10
|
|
||||||
}
|
|
||||||
|
|
||||||
access_configuration = {
|
|
||||||
master_ip_space = "no-needed"
|
|
||||||
master_access_list = jsonencode(["10.0.0.0/8"])
|
|
||||||
slave_ip_space = "no-needed"
|
|
||||||
slave_access_list = jsonencode([])
|
|
||||||
}
|
|
||||||
|
|
||||||
postgres_configuration = {
|
|
||||||
version = "17"
|
|
||||||
ssl_required = true
|
|
||||||
pooler_master = false
|
|
||||||
pooler_slave = false
|
|
||||||
}
|
|
||||||
|
|
||||||
postgres_conf = jsonencode([{
|
|
||||||
param_name = "log_connections"
|
|
||||||
param_value = ""
|
|
||||||
}])
|
|
||||||
|
|
||||||
backup_configuration = {
|
|
||||||
s3_uid = var.s3_uid
|
|
||||||
retain = 14
|
|
||||||
schedule = "0 0 * * *"
|
|
||||||
}
|
|
||||||
|
|
||||||
autoscale_configuration = {
|
|
||||||
enabled = false
|
|
||||||
schedule = 0
|
|
||||||
percent = 10
|
|
||||||
quota = 100
|
|
||||||
}
|
|
||||||
|
|
||||||
mtls_configuration = {
|
|
||||||
type = "off"
|
|
||||||
duration_ca = 175200
|
|
||||||
duration_server = 87600
|
|
||||||
}
|
|
||||||
|
|
||||||
operation_timeout = "11m"
|
|
||||||
adopt_existing_on_create = true
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
# =============================================================================
|
|
||||||
# PostgreSQL — пользователи (6 шт.)
|
|
||||||
# =============================================================================
|
|
||||||
resource "nubes_postgres_user" "pg_user_0" {
|
|
||||||
postgres_id = nubes_postgres.npg.id
|
|
||||||
username = "user0"
|
|
||||||
role = "ddl_user"
|
|
||||||
mtls_access = false
|
|
||||||
adopt_existing_on_create = true
|
|
||||||
}
|
|
||||||
|
|
||||||
# resource "nubes_postgres_user" "pg_user_1" {
|
|
||||||
# postgres_id = nubes_postgres.npg.id
|
|
||||||
# username = "user1"
|
|
||||||
# role = "ddl_user"
|
|
||||||
# adopt_existing_on_create = true
|
|
||||||
# }
|
|
||||||
|
|
||||||
# # =============================================================================
|
|
||||||
# # PostgreSQL — базы данных (3 шт.)
|
|
||||||
# # =============================================================================
|
|
||||||
# resource "nubes_postgres_database" "pg_db_1" {
|
|
||||||
# postgres_id = nubes_postgres.npg.id
|
|
||||||
# db_name = "dbapp1"
|
|
||||||
# db_owner = nubes_postgres_user.pg_user_1.username
|
|
||||||
# adopt_existing_on_create = true
|
|
||||||
# }
|
|
||||||
|
|
||||||
resource "nubes_postgres_database" "pg_db_2" {
|
|
||||||
postgres_id = nubes_postgres.npg.id
|
|
||||||
db_name = "dbapp2"
|
|
||||||
db_owner = nubes_postgres_user.pg_user_0.username
|
|
||||||
adopt_existing_on_create = true
|
|
||||||
}
|
|
||||||
|
|
||||||
# resource "nubes_postgres_database" "pg_db_3" {
|
|
||||||
# postgres_id = nubes_postgres.npg.id
|
|
||||||
# db_name = "dbapp3"
|
|
||||||
# db_owner = nubes_postgres_user.pg_user_1.username
|
|
||||||
# adopt_existing_on_create = true
|
|
||||||
# }
|
|
||||||
|
|
||||||
# S3 bucket — замени "buck0" на своё имя везде ниже
|
|
||||||
resource "nubes_s3bucket" "bukka0" { # ← замени buck0 на своё имя ресурса
|
|
||||||
resource_name = "btst" # ← замени buck0 на своё имя ресурса
|
|
||||||
#s3_user_uid = "naeel-s3"
|
|
||||||
s3_user_uid = var.s3_user_uid
|
|
||||||
bucket_name = "bucktst000" # ← замени buck0 на своё имя бакета
|
|
||||||
adopt_existing_on_create = true
|
|
||||||
}
|
|
||||||
@@ -22,10 +22,6 @@ variable "realm" {
|
|||||||
sensitive = true
|
sensitive = true
|
||||||
description = "resource_realm parameter for nubes_postgres resource"
|
description = "resource_realm parameter for nubes_postgres resource"
|
||||||
}
|
}
|
||||||
variable "s3_user_uid" {
|
|
||||||
type = string
|
|
||||||
description = "S3 user UUID"
|
|
||||||
}
|
|
||||||
|
|
||||||
provider "nubes" {
|
provider "nubes" {
|
||||||
api_token = var.api_token
|
api_token = var.api_token
|
||||||
|
|||||||
@@ -9,23 +9,6 @@ resource "nubes_postgres_user" "pg_user_0" {
|
|||||||
adopt_existing_on_create = true
|
adopt_existing_on_create = true
|
||||||
}
|
}
|
||||||
|
|
||||||
# resource "nubes_postgres_user" "pg_user_1" {
|
|
||||||
# postgres_id = nubes_postgres.npg.id
|
|
||||||
# username = "user1"
|
|
||||||
# role = "ddl_user"
|
|
||||||
# adopt_existing_on_create = true
|
|
||||||
# }
|
|
||||||
|
|
||||||
# # =============================================================================
|
|
||||||
# # PostgreSQL — базы данных (3 шт.)
|
|
||||||
# # =============================================================================
|
|
||||||
# resource "nubes_postgres_database" "pg_db_1" {
|
|
||||||
# postgres_id = nubes_postgres.npg.id
|
|
||||||
# db_name = "dbapp1"
|
|
||||||
# db_owner = nubes_postgres_user.pg_user_1.username
|
|
||||||
# adopt_existing_on_create = true
|
|
||||||
# }
|
|
||||||
|
|
||||||
resource "nubes_postgres_database" "pg_db_2" {
|
resource "nubes_postgres_database" "pg_db_2" {
|
||||||
postgres_id = nubes_postgres.npg.id
|
postgres_id = nubes_postgres.npg.id
|
||||||
db_name = "dbapp2"
|
db_name = "dbapp2"
|
||||||
@@ -33,18 +16,11 @@ resource "nubes_postgres_database" "pg_db_2" {
|
|||||||
adopt_existing_on_create = true
|
adopt_existing_on_create = true
|
||||||
}
|
}
|
||||||
|
|
||||||
# resource "nubes_postgres_database" "pg_db_3" {
|
|
||||||
# postgres_id = nubes_postgres.npg.id
|
|
||||||
# db_name = "dbapp3"
|
|
||||||
# db_owner = nubes_postgres_user.pg_user_1.username
|
|
||||||
# adopt_existing_on_create = true
|
|
||||||
# }
|
|
||||||
|
|
||||||
# S3 bucket — замени "buck0" на своё имя везде ниже
|
# S3 bucket — замени "buck0" на своё имя везде ниже
|
||||||
resource "nubes_s3bucket" "bukka0" { # ← замени buck0 на своё имя ресурса
|
resource "nubes_s3bucket" "bukka0" { # ← замени buck0 на своё имя ресурса
|
||||||
resource_name = "btst" # ← замени buck0 на своё имя ресурса
|
resource_name = "btst" # ← замени buck0 на своё имя ресурса
|
||||||
#s3_user_uid = "naeel-s3"
|
s3_user_uid = "naeel-s3"
|
||||||
s3_user_uid = var.s3_user_uid
|
# s3_user_uid = var.s3_user_uid
|
||||||
bucket_name = "bucktst000" # ← замени buck0 на своё имя бакета
|
bucket_name = "bucktst000" # ← замени buck0 на своё имя бакета
|
||||||
adopt_existing_on_create = true
|
adopt_existing_on_create = true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ rsync -avz --delete \
|
|||||||
--exclude='.terraform/' \
|
--exclude='.terraform/' \
|
||||||
--exclude='terraform.tfstate*' \
|
--exclude='terraform.tfstate*' \
|
||||||
--exclude='.terraform.lock.hcl' \
|
--exclude='.terraform.lock.hcl' \
|
||||||
|
--exclude='IOT_RMQ_DEMO_VM/' \
|
||||||
-e "ssh -i ${SSH_KEY} -o ConnectTimeout=10" \
|
-e "ssh -i ${SSH_KEY} -o ConnectTimeout=10" \
|
||||||
"${LOCAL_PATH}/" \
|
"${LOCAL_PATH}/" \
|
||||||
"${VM_HOST}:${VM_PATH}/"
|
"${VM_HOST}:${VM_PATH}/"
|
||||||
|
|||||||
@@ -6,20 +6,19 @@
|
|||||||
|
|
||||||
| Ресурс | Имя в манифесте | Назначение |
|
| Ресурс | Имя в манифесте | Назначение |
|
||||||
|--------|----------------|-----------|
|
|--------|----------------|-----------|
|
||||||
| `nubes_postgres` | `main_pg` | Кластер PostgreSQL (1 реплика, 500m CPU, 512MB RAM, 10GB диск) |
|
| `nubes_postgres` | `main_pg` | Кластер PostgreSQL |
|
||||||
| `nubes_postgres_user` | `app_user` | Пользователь БД с правами `ddl_user` |
|
| `nubes_postgres_user` | `app_user` | Пользователь БД |
|
||||||
| `nubes_postgres_database` | `app_db` | База данных, владелец — `app_user` |
|
| `nubes_postgres_database` | `app_db` | База данных |
|
||||||
| `nubes_s3bucket` | `backups` | S3-бакет для хранения бэкапов |
|
| `nubes_s3bucket` | `backups` | S3-бакет для бэкапов |
|
||||||
|
|
||||||
## Переменные
|
## Переменные
|
||||||
|
|
||||||
Создай `terraform.tfvars`:
|
Создай `terraform.tfvars`:
|
||||||
|
|
||||||
```hcl
|
```hcl
|
||||||
api_token = "***" # токен из Личного кабинета
|
api_token = "***" # токен из Личного кабинета
|
||||||
realm = "k8s-3-sandbox-nubes-ru" # кластер Kubernetes
|
realm = "k8s-3-sandbox-nubes-ru" # кластер Kubernetes (из организации)
|
||||||
s3_uid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" # UUID твоего S3
|
s3_name = "my-s3" # ИМЯ экземпляра S3 (не UUID!)
|
||||||
s3_user_uid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" # UUID пользователя S3
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Провайдер
|
## Провайдер
|
||||||
@@ -34,10 +33,9 @@ terraform {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "api_token" { type = string; sensitive = true }
|
variable "api_token" { type = string; sensitive = true }
|
||||||
variable "realm" { type = string }
|
variable "realm" { type = string }
|
||||||
variable "s3_uid" { type = string }
|
variable "s3_name" { type = string }
|
||||||
variable "s3_user_uid" { type = string }
|
|
||||||
|
|
||||||
provider "nubes" {
|
provider "nubes" {
|
||||||
api_token = var.api_token
|
api_token = var.api_token
|
||||||
@@ -49,72 +47,77 @@ provider "nubes" {
|
|||||||
|
|
||||||
```hcl
|
```hcl
|
||||||
resource "nubes_postgres" "main_pg" {
|
resource "nubes_postgres" "main_pg" {
|
||||||
resource_name = "my-postgres"
|
resource_name = "my-postgres" # любое имя
|
||||||
|
|
||||||
|
# На каком кластере Kubernetes развернуть
|
||||||
startup_configuration = {
|
startup_configuration = {
|
||||||
resource_realm = var.realm
|
resource_realm = var.realm # имя кластера
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Ресурсы пода
|
||||||
cluster_configuration = {
|
cluster_configuration = {
|
||||||
cpu = 500 # milicores (1000 = 1 ядро)
|
cpu = 500 # milicores (1000 = 1 ядро)
|
||||||
memory = 512 # megabytes
|
memory = 512 # megabytes
|
||||||
replicas = 1 # 1, 3, 5 или 7
|
replicas = 1 # 1, 3, 5 или 7
|
||||||
disk = 10 # gigabytes
|
disk = 10 # gigabytes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Сетевой доступ
|
||||||
access_configuration = {
|
access_configuration = {
|
||||||
master_ip_space = "no-needed"
|
master_ip_space = "no-needed" # Ip-Space для внешнего IP мастера
|
||||||
master_access_list = jsonencode(["10.0.0.0/8"])
|
master_access_list = jsonencode(["10.0.0.0/8"]) # кому доступ к мастеру
|
||||||
slave_ip_space = "no-needed"
|
slave_ip_space = "no-needed" # Ip-Space для внешнего IP слейва
|
||||||
slave_access_list = jsonencode([])
|
slave_access_list = jsonencode([]) # кому доступ к слейву ([] = всем)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Версия и настройки PostgreSQL
|
||||||
postgres_configuration = {
|
postgres_configuration = {
|
||||||
version = "17"
|
version = "17" # 16 или 17
|
||||||
ssl_required = true
|
ssl_required = true # требовать SSL
|
||||||
pooler_master = false
|
pooler_master = false # PgBouncer для записи
|
||||||
pooler_slave = false
|
pooler_slave = false # PgBouncer для чтения
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Резервное копирование
|
||||||
backup_configuration = {
|
backup_configuration = {
|
||||||
s3_uid = var.s3_uid
|
s3_uid = var.s3_name # ИМЯ S3 (не UUID!)
|
||||||
retain = 14 # хранить 14 копий
|
retain = 14 # сколько бэкапов хранить
|
||||||
schedule = "0 0 * * *" # ежедневно в полночь
|
schedule = "0 0 * * *" # cron (ежедневно в полночь)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Автоскейлинг диска
|
||||||
autoscale_configuration = {
|
autoscale_configuration = {
|
||||||
enabled = false
|
enabled = false # выключен
|
||||||
schedule = 0
|
schedule = 0 # час окна (0-23)
|
||||||
percent = 10
|
percent = 10 # % расширения
|
||||||
quota = 100
|
quota = 100 # макс. размер диска (GB)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Mutual TLS
|
||||||
mtls_configuration = {
|
mtls_configuration = {
|
||||||
type = "off"
|
type = "off" # off | manual | auto
|
||||||
duration_ca = 175200
|
duration_ca = 175200 # время жизни CA (часы)
|
||||||
duration_server = 87600
|
duration_server = 87600 # время жизни сертификата (часы)
|
||||||
}
|
}
|
||||||
|
|
||||||
operation_timeout = "11m"
|
operation_timeout = "11m" # таймаут операции
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Пользователь и база данных
|
## Пользователь и база данных
|
||||||
|
|
||||||
```hcl
|
```hcl
|
||||||
# Пользователь с правами создания БД и ролей
|
|
||||||
resource "nubes_postgres_user" "app_user" {
|
resource "nubes_postgres_user" "app_user" {
|
||||||
postgres_id = nubes_postgres.main_pg.id
|
postgres_id = nubes_postgres.main_pg.id # ссылка на кластер
|
||||||
username = "app_user"
|
username = "app_user" # имя пользователя
|
||||||
role = "ddl_user" # app_user — только DML; ddl_user — DDL + DML
|
role = "ddl_user" # app_user (DML) | ddl_user (DDL)
|
||||||
mtls_access = false
|
mtls_access = false # mTLS для пользователя
|
||||||
}
|
}
|
||||||
|
|
||||||
# База данных, владелец — созданный выше пользователь
|
|
||||||
resource "nubes_postgres_database" "app_db" {
|
resource "nubes_postgres_database" "app_db" {
|
||||||
postgres_id = nubes_postgres.main_pg.id
|
postgres_id = nubes_postgres.main_pg.id # ссылка на кластер
|
||||||
db_name = "my_app_db"
|
db_name = "my_app_db" # имя базы данных
|
||||||
db_owner = nubes_postgres_user.app_user.username
|
db_owner = nubes_postgres_user.app_user.username # владелец
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -122,9 +125,9 @@ resource "nubes_postgres_database" "app_db" {
|
|||||||
|
|
||||||
```hcl
|
```hcl
|
||||||
resource "nubes_s3bucket" "backups" {
|
resource "nubes_s3bucket" "backups" {
|
||||||
resource_name = "pg-backup-bucket"
|
resource_name = "pg-backup-bucket" # любое имя
|
||||||
s3_user_uid = var.s3_user_uid
|
s3_user_uid = var.s3_name # ИМЯ S3 (не UUID!)
|
||||||
bucket_name = "my-app-backups"
|
bucket_name = "my-app-backups" # имя бакета
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -135,4 +138,4 @@ terraform init
|
|||||||
terraform apply
|
terraform apply
|
||||||
```
|
```
|
||||||
|
|
||||||
Все четыре ресурса создаются за один `apply`. Порядок не важен — Terraform сам выстроит зависимости: сначала кластер, потом пользователь, потом БД и бакет.
|
Все 4 ресурса за один `apply`. Terraform сам выстроит порядок: кластер → пользователь → БД → бакет.
|
||||||
|
|||||||
Reference in New Issue
Block a user