diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index c00765d..1b7470e 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -8,7 +8,9 @@ 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 @@ -16,7 +18,9 @@ jobs: 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 diff --git a/_locals.tf b/_locals.tf index 942e361..4e640d4 100644 --- a/_locals.tf +++ b/_locals.tf @@ -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 } ] ]) @@ -16,10 +18,15 @@ 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 } ] ]) + 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", ] diff --git a/roles.tf b/roles.tf index 6cd328f..28968f7 100644 --- a/roles.tf +++ b/roles.tf @@ -1,5 +1,5 @@ resource "random_password" "role" { - for_each = var.roles + for_each = local.roles_built_in length = 48 min_lower = 0 @@ -19,7 +19,7 @@ resource "random_password" "role" { resource "mysql_user" "users" { for_each = { - for username, user in var.roles : username => user if !user.is_iam_user + for username, user in local.roles_built_in : username => user } user = each.key @@ -32,8 +32,8 @@ resource "mysql_grant" "users_ro" { for databases_readers in local.databases_readers : "${databases_readers.database}.${databases_readers.role}" => databases_readers } - user = each.value.role - host = "%" + user = each.value.is_iam ? split("@", each.value.role)[0] : each.value.role + host = each.value.type == "CLOUD_IAM_GROUP" ? split("@", each.value.role)[1] : "%" database = each.value.database privileges = local.privileges_ro table = "*" @@ -44,8 +44,8 @@ resource "mysql_grant" "users_rw" { for database_writer in local.databases_writers : "${database_writer.database}.${database_writer.role}" => database_writer } - user = each.value.role - host = "%" + user = each.value.is_iam ? split("@", each.value.role)[0] : each.value.role + host = each.value.type == "CLOUD_IAM_GROUP" ? split("@", each.value.role)[1] : "%" database = each.value.database privileges = local.privileges_rw table = "*" diff --git a/users-iam.tf b/users-iam.tf new file mode 100644 index 0000000..341206f --- /dev/null +++ b/users-iam.tf @@ -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 +} diff --git a/variables.tf b/variables.tf index cd2aa35..a131253 100644 --- a/variables.tf +++ b/variables.tf @@ -1,8 +1,20 @@ +variable "instance_id" { + type = string + default = null +} + variable "roles" { type = map(object({ connection_limit = optional(number) databases_ro = list(string) databases_rw = list(string) is_iam_user = bool + 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." + } }