Files
factory/postgres/iac/main.tf
2025-08-09 17:01:18 +02:00

97 lines
2.7 KiB
HCL

resource "random_password" "credentials_editor" {
length = 24
override_special = "-:!+<>"
}
resource "postgresql_role" "credentials_editor" {
name = "credentials_editor"
login = true
password = random_password.credentials_editor.result
create_role = true
lifecycle {
ignore_changes = [
roles,
]
}
}
resource "vault_kv_secret" "postgres_admin_credentials" {
path = "kvv1/postgres/credentials_editor/credentials"
data_json = jsonencode({
username = postgresql_role.credentials_editor.name
password = postgresql_role.credentials_editor.password
})
}
resource "postgresql_role" "app_role" {
for_each = var.applications
name = "${each.value}_role"
login = false
}
resource "postgresql_grant_role" "credentials_editor_app_role" {
for_each = var.applications
role = postgresql_role.credentials_editor.name
grant_role = postgresql_role.app_role[each.value].name
with_admin_option = true
}
resource "postgresql_database" "app_db" {
for_each = var.applications
name = each.value
owner = postgresql_role.app_role[each.value].name
template = "template0"
alter_object_ownership = true
}
resource "postgresql_function" "pgbouncer_user_lookup" {
for_each = var.applications
name = "user_lookup"
database = postgresql_database.app_db[each.value].name
arg {
mode = "IN"
name = "i_username"
type = "text"
}
arg {
mode = "OUT"
name = "uname"
type = "text"
}
arg {
mode = "OUT"
name = "phash"
type = "text"
}
returns = "record"
language = "plpgsql"
body = <<-EOF
BEGIN
SELECT usename, passwd FROM pg_catalog.pg_shadow
WHERE usename = i_username INTO uname, phash;
RETURN;
END;
EOF
parallel = "SAFE"
security_definer = true
}
resource "postgresql_grant" "pgbouncer_user_lookup_public_revoke" {
for_each = var.applications
database = postgresql_function.pgbouncer_user_lookup[each.value].database
role = "public"
schema = "public"
object_type = "function"
objects = [
postgresql_function.pgbouncer_user_lookup[each.value].name,
]
privileges = []
}
resource "postgresql_grant" "pgbouncer_user_lookup" {
depends_on = [ postgresql_grant.pgbouncer_user_lookup_public_revoke ] # can't do both in parallel
for_each = var.applications
database = postgresql_function.pgbouncer_user_lookup[each.value].database
role = "pgbouncer_auth"
schema = "public"
object_type = "function"
objects = [
postgresql_function.pgbouncer_user_lookup[each.value].name,
]
privileges = ["EXECUTE"]
}