Files
sless/examples/POSTGRES/resources.tf
T

174 lines
6.1 KiB
Terraform

// 2026-03-18 — добавлены locals для извлечения credentials из vault_secrets (без хардкода).
// Для сверки хардкод остаётся в terraform.tfvars на этапе разработки.
// sless_function и sless_job закомментированы — сначала проверяется сетевое соединение.
# Актуальные credentials из vault_secrets (authoritatively) — vault синхронизирован с кластером.
# Структура vault_secrets["users"]: JSON-строка {"username": {"password": "...", "username": "..."}}
locals {
pg_creds_map = jsondecode(nubes_postgres.npg.vault_secrets["users"])
pg_username = nubes_postgres_user.pg_user.username
pg_password = local.pg_creds_map[local.pg_username]["password"]
pg_host = nubes_postgres.npg.state_out_flat["internalConnect.master"]
pg_database = nubes_postgres_database.db.db_name
}
resource "nubes_postgres" "npg" {
resource_name = "teststand-pg-2"
# s3_uid = "s01325"
s3_uid = var.s3_uid
resource_realm = var.realm
resource_instances = 1
resource_memory = 512
resource_c_p_u = 500
resource_disk = "1"
app_version = "17"
json_parameters = jsonencode({
log_connections = "off"
log_disconnections = "off"
})
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
# suspend_on_destroy = false
operation_timeout = "11m"
adopt_existing_on_create = true
}
resource "nubes_postgres_user" "pg_user" {
postgres_id = nubes_postgres.npg.id
username = "u-user0"
role = "ddl_user"
adopt_existing_on_create = true
}
resource "nubes_postgres_database" "db" {
postgres_id = nubes_postgres.npg.id
db_name = "db_terra"
db_owner = nubes_postgres_user.pg_user.username
adopt_existing_on_create = true
# suspend_on_destroy = false
}
# Служебная функция выполняет SQL-операторы из event_json.
# Credentials берутся из locals (vault_secrets) — без хардкода.
# Для сверки хардкод остаётся в terraform.tfvars.
resource "sless_function" "postgres_sql_runner_create_table" {
name = "pg-create-table-runner"
runtime = "python3.11"
entrypoint = "sql_runner.run_sql"
memory_mb = 128
timeout_sec = 30
env_vars = {
PGHOST = local.pg_host
PGPORT = "5432"
PGDATABASE = local.pg_database
PGUSER = local.pg_username
PGPASSWORD = local.pg_password
PGSSLMODE = "require"
# Для сверки (должно совпадать с vault):
# PGUSER = var.pg_user
# PGPASSWORD = var.pg_password
}
source_dir = "${path.module}/code/sql-runner"
}
resource "sless_job" "postgres_table_init_job" {
name = "pg-create-table-job-main-v13"
function = sless_function.postgres_sql_runner_create_table.name
wait_timeout_sec = 180
run_id = 13
event_json = jsonencode({
statements = [
"CREATE TABLE IF NOT EXISTS terraform_demo_table (id serial PRIMARY KEY, title text NOT NULL, created_at timestamp DEFAULT now())"
]
})
depends_on = [nubes_postgres_database.db]
}
# HTTP-функция читает строки из terraform_demo_table и возвращает JSON.
# Использует те же credentials что и sql-runner.
# Доступна по URL: https://sless.kube5s.ru/fn/<namespace>/pg-table-reader
resource "sless_function" "postgres_table_reader" {
name = "pg-table-reader"
runtime = "python3.11"
entrypoint = "table_reader.list_rows"
memory_mb = 128
timeout_sec = 30
env_vars = {
PGHOST = local.pg_host
PGPORT = "5432"
PGDATABASE = local.pg_database
PGUSER = local.pg_username
PGPASSWORD = local.pg_password
PGSSLMODE = "require"
}
source_dir = "${path.module}/code/table-reader"
depends_on = [sless_job.postgres_table_init_job]
}
resource "sless_trigger" "postgres_table_reader_http" {
name = "pg-table-reader-http"
type = "http"
function = sless_function.postgres_table_reader.name
enabled = true
}
output "table_reader_url" {
value = sless_trigger.postgres_table_reader_http.url
}
# Namespace пользователя — извлекаем из уже известного URL триггера.
# URL формат: https://sless.kube5s.ru/fn/sless-{hex16}/{name}
# split("/") → ["https:", "", "sless.kube5s.ru", "fn", "sless-{hex16}", "{name}"]
# element(..., 4) → "sless-{hex16}"
locals {
user_namespace = element(split("/", sless_trigger.postgres_table_reader_http.url), 4)
}
# HTTP-функция возвращает список всех функций пользователя с их статусами и триггерами.
# Вызывает внутренний API оператора — не проходит через внешний Ingress.
# Доступна по URL: https://sless.kube5s.ru/fn/<namespace>/funcs
resource "sless_function" "funcs_list" {
name = "funcs"
runtime = "python3.11"
entrypoint = "funcs_list.list_all"
memory_mb = 128
timeout_sec = 15
env_vars = {
# Внутренний ClusterIP сервис оператора — без TLS, без DNS-overhead.
SLESS_API_URL = "http://sless-operator.sless.svc.cluster.local:9090"
SLESS_NAMESPACE = local.user_namespace
SLESS_TOKEN = var.api_token
}
source_dir = "${path.module}/code/funcs-list"
depends_on = [sless_trigger.postgres_table_reader_http]
}
resource "sless_trigger" "funcs_list_http" {
name = "funcs-http"
type = "http"
function = sless_function.funcs_list.name
enabled = true
}
output "funcs_url" {
value = sless_trigger.funcs_list_http.url
}