Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,19 @@ jobs:
check-formatting:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: hashicorp/setup-terraform@v3

- uses: actions/checkout@v5

- name: Check formatting
run: terraform fmt -check

validate-module:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: hashicorp/setup-terraform@v3

- uses: actions/checkout@v5

- name: Run terraform init
run: terraform init
Expand Down
9 changes: 9 additions & 0 deletions locals.tf
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ locals {
for database in role_.databases_ro : {
role = role
database = database
is_iam = contains(["CLOUD_IAM_USER", "CLOUD_IAM_GROUP", "CLOUD_IAM_SERVICE_ACCOUNT"], role_.type)
type = role_.type
}
]
])
Expand All @@ -16,17 +18,24 @@ locals {
for database in role_.databases_rw : {
role = role
database = database
is_iam = contains(["CLOUD_IAM_USER", "CLOUD_IAM_GROUP", "CLOUD_IAM_SERVICE_ACCOUNT"], role_.type)
type = role_.type
}
]
], [
for database in local.databases : [
for writer in var.legacy_writers : {
role = writer
database = database
is_iam = false
type = "BUILT_IN"
}
]
]))

roles_iam = { for role, role_ in var.roles : role => role_ if contains(["CLOUD_IAM_USER", "CLOUD_IAM_GROUP", "CLOUD_IAM_SERVICE_ACCOUNT"], role_.type) }
roles_built_in = { for role, role_ in var.roles : role => role_ if role_.type == "BUILT_IN" }

privileges_ro = [
"SELECT",
]
Expand Down
33 changes: 20 additions & 13 deletions roles.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
resource "random_password" "role" {
for_each = var.roles
for_each = local.roles_built_in

length = 48
min_lower = 0
Expand All @@ -18,7 +18,7 @@ resource "random_password" "role" {
}

resource "postgresql_role" "role" {
for_each = var.roles
for_each = local.roles_built_in

name = each.key
superuser = false
Expand Down Expand Up @@ -75,6 +75,15 @@ resource "postgresql_role" "role_ro" {
statement_timeout = 0
}

resource "postgresql_grant_role" "role_ro" {
for_each = {
for role in local.databases_readers : "${role.database}__${role.role}" => role if role.is_iam
}

role = each.value.role
grant_role = "${each.value.database}_role_ro"
}

resource "postgresql_default_privileges" "role_ro_table" {
for_each = {
for database_writer in local.databases_writers : "${database_writer.database}.${database_writer.role}" => database_writer
Expand Down Expand Up @@ -158,6 +167,15 @@ resource "postgresql_role" "role_rw" {
statement_timeout = 0
}

resource "postgresql_grant_role" "role_rw" {
for_each = {
for role in local.databases_writers : "${role.database}__${role.role}" => role if role.is_iam
}

role = each.value.role
grant_role = "${each.value.database}_role_rw"
}

resource "postgresql_default_privileges" "role_rw_table" {
for_each = {
for database_writer in local.databases_writers : "${database_writer.database}.${database_writer.role}" => database_writer
Expand Down Expand Up @@ -218,14 +236,3 @@ resource "postgresql_grant" "role_rw_schema" {
privileges = ["CREATE", "USAGE"]
with_grant_option = false
}


moved {
from = postgresql_default_privileges.role_ro
to = postgresql_default_privileges.role_ro_table
}

moved {
from = postgresql_default_privileges.role_rw
to = postgresql_default_privileges.role_rw_table
}
7 changes: 7 additions & 0 deletions users-iam.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
resource "google_sql_user" "iam" {
for_each = local.roles_iam

instance = var.instance_id
name = each.key
type = each.value.type
}
13 changes: 13 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,23 @@ variable "legacy_writers" {
default = []
}

variable "instance_id" {
type = string
default = null
}

variable "roles" {
type = map(object({
connection_limit = optional(number)
databases_ro = list(string)
databases_rw = list(string)
type = optional(string, "BUILT_IN")
}))

validation {
condition = alltrue([
for u in var.roles : contains(["BUILT_IN", "CLOUD_IAM_USER", "CLOUD_IAM_GROUP", "CLOUD_IAM_SERVICE_ACCOUNT"], u.type)
])
error_message = "Invalid user type. Only BUILT_IN, CLOUD_IAM_USER, CLOUD_IAM_GROUP, CLOUD_IAM_SERVICE_ACCOUNT are supported."
}
}