Example Terraform configuration for testing PostgreSQL integration: - main.tf: VPC and database setup - postgres.tf: Database resource definitions - outputs.tf: Output values for connection - test_basic.sh: Basic connectivity tests - test_lifecycle.sh: Full lifecycle testing - terraform.tfvars.example: Configuration template - .gitignore: Ignore sensitive data and terraform artifacts
100 lines
4.9 KiB
HCL
100 lines
4.9 KiB
HCL
// 2026-04-01 — postgres.tf: Managed PostgreSQL инстанс, пользователь и база данных.
|
||
//
|
||
// Порядок создания:
|
||
// 1. nubes_postgres — сам инстанс PostgreSQL
|
||
// 2. nubes_postgres_user — пользователь; пароль автоматически попадает в vault_secrets
|
||
// 3. nubes_postgres_database — база данных с owner = созданный пользователь
|
||
//
|
||
// Важно: vault_secrets["users"] появляется только ПОСЛЕ первого apply (нет пользователя — нет ключа).
|
||
// try() в locals страхует от ошибки на первом прогоне.
|
||
|
||
// ── Locals: credentials из vault ─────────────────────────────────────────────
|
||
|
||
locals {
|
||
# Карта username→{password, username} из vault_secrets, который Nubes заполняет после
|
||
# создания пользователя. try() нужен для первого apply, когда ключа ещё нет.
|
||
pg_creds_map = try(
|
||
jsondecode(lookup(nubes_postgres.pg_test_instance.vault_secrets, "users", "{}")),
|
||
{}
|
||
)
|
||
pg_password = try(local.pg_creds_map[var.pg_username]["password"], "")
|
||
|
||
# Адрес master-ноды (внутренний — для подключения из кластера).
|
||
pg_host = nubes_postgres.pg_test_instance.state_out_flat["internalConnect.master"]
|
||
pg_port = 5432
|
||
}
|
||
|
||
// ── Инстанс PostgreSQL ────────────────────────────────────────────────────────
|
||
|
||
resource "nubes_postgres" "pg_test_instance" {
|
||
resource_name = var.pg_resource_name
|
||
s3_uid = var.s3_uid
|
||
resource_realm = var.realm
|
||
|
||
# Минимальные ресурсы — достаточно для тестирования.
|
||
resource_instances = 1
|
||
resource_memory = 512 # MiB
|
||
resource_c_p_u = 500 # millicores
|
||
resource_disk = "1" # GiB
|
||
app_version = "17"
|
||
|
||
# json_parameters убран — при передаче пустого объекта API возвращает "Invalid JSON String".
|
||
# Если нужны кастомные параметры PG — добавить после диагностики.
|
||
|
||
# Pooler не нужен для тестов — упрощает топологию.
|
||
enable_pg_pooler_master = false
|
||
enable_pg_pooler_slave = false
|
||
|
||
allow_no_s_s_l = false
|
||
auto_scale = false
|
||
auto_scale_percentage = 10
|
||
auto_scale_tech_window = 0
|
||
auto_scale_quota_gb = "1"
|
||
|
||
# Внешний адрес не нужен — подключаемся изнутри кластера.
|
||
need_external_address_master = false
|
||
|
||
operation_timeout = "11m"
|
||
|
||
# Позволяет импортировать уже существующий инстанс с тем же именем, не падая
|
||
# с "already exists" — удобно при повторном apply после ручного создания.
|
||
adopt_existing_on_create = true
|
||
}
|
||
|
||
// ── Пользователь ──────────────────────────────────────────────────────────────
|
||
|
||
resource "nubes_postgres_user" "pg_test_user" {
|
||
postgres_id = nubes_postgres.pg_test_instance.id
|
||
username = var.pg_username
|
||
role = var.pg_role
|
||
|
||
# Не падать если пользователь с таким именем уже существует.
|
||
adopt_existing_on_create = true
|
||
}
|
||
|
||
resource "nubes_postgres_user" "pg_test_user3" {
|
||
postgres_id = nubes_postgres.pg_test_instance.id
|
||
username = "u3"
|
||
role = var.pg_role
|
||
|
||
depends_on = [nubes_postgres_user.pg_test_user]
|
||
# Не падать если пользователь с таким именем уже существует.
|
||
adopt_existing_on_create = true
|
||
}
|
||
|
||
// ── База данных ───────────────────────────────────────────────────────────────
|
||
|
||
resource "nubes_postgres_database" "pg_test_db" {
|
||
postgres_id = nubes_postgres.pg_test_instance.id
|
||
db_name = var.pg_db_name
|
||
db_owner = nubes_postgres_user.pg_test_user.username
|
||
|
||
# Не падать если БД уже существует.
|
||
adopt_existing_on_create = true
|
||
|
||
# ВАЖНО: из-за ограничения API Nubes (ERR-PG-08: "Concurrent operations are not supported")
|
||
# нужно явно ждать пользователя даже если он не выглядит dependency.
|
||
# других ресурс на инстансе ещё обрабатывает операции.
|
||
depends_on = [nubes_postgres_user.pg_test_user3]
|
||
}
|