role management for postgres synergy with vault dynamic credentials
This commit is contained in:
97
postgres/iac/main.tf
Normal file
97
postgres/iac/main.tf
Normal file
@@ -0,0 +1,97 @@
|
||||
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"]
|
||||
}
|
||||
Reference in New Issue
Block a user