diff --git a/fast/stages/2-security/core-dev.tf b/fast/stages/2-security/core-dev.tf index 2197a2caa..57f3120b9 100644 --- a/fast/stages/2-security/core-dev.tf +++ b/fast/stages/2-security/core-dev.tf @@ -33,6 +33,12 @@ module "dev-sec-project" { iam = { "roles/cloudkms.viewer" = local.dev_kms_restricted_admins } + iam_bindings_additive = { + for member in local.dev_kms_restricted_admins : + "kms_restricted_admin.${member}" => merge(local.kms_restricted_admin_template, { + member = member + }) + } labels = { environment = "dev", team = "security" } services = local.project_services } @@ -47,24 +53,3 @@ module "dev-sec-kms" { } keys = local.kms_locations_keys[each.key] } - -# TODO(ludo): add support for conditions to Fabric modules - -resource "google_project_iam_member" "dev_key_admin_delegated" { - for_each = toset(local.dev_kms_restricted_admins) - project = module.dev-sec-project.project_id - role = "roles/cloudkms.admin" - member = each.key - condition { - title = "kms_sa_delegated_grants" - description = "Automation service account delegated grants." - expression = format( - "api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s]) && resource.type == 'cloudkms.googleapis.com/CryptoKey'", - join(",", formatlist("'%s'", [ - "roles/cloudkms.cryptoKeyEncrypterDecrypter", - "roles/cloudkms.cryptoKeyEncrypterDecrypterViaDelegation" - ])) - ) - } - depends_on = [module.dev-sec-project] -} diff --git a/fast/stages/2-security/core-prod.tf b/fast/stages/2-security/core-prod.tf index 276cb4322..c0b35dd6e 100644 --- a/fast/stages/2-security/core-prod.tf +++ b/fast/stages/2-security/core-prod.tf @@ -32,6 +32,12 @@ module "prod-sec-project" { iam = { "roles/cloudkms.viewer" = local.prod_kms_restricted_admins } + iam_bindings_additive = { + for member in local.prod_kms_restricted_admins : + "kms_restricted_admin.${member}" => merge(local.kms_restricted_admin_template, { + member = member + }) + } labels = { environment = "prod", team = "security" } services = local.project_services } @@ -46,24 +52,3 @@ module "prod-sec-kms" { } keys = local.kms_locations_keys[each.key] } - -# TODO(ludo): add support for conditions to Fabric modules - -resource "google_project_iam_member" "prod_key_admin_delegated" { - for_each = toset(local.prod_kms_restricted_admins) - project = module.prod-sec-project.project_id - role = "roles/cloudkms.admin" - member = each.key - condition { - title = "kms_sa_delegated_grants" - description = "Automation service account delegated grants." - expression = format( - "api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s]) && resource.type == 'cloudkms.googleapis.com/CryptoKey'", - join(",", formatlist("'%s'", [ - "roles/cloudkms.cryptoKeyEncrypterDecrypter", - "roles/cloudkms.cryptoKeyEncrypterDecrypterViaDelegation" - ])) - ) - } - depends_on = [module.prod-sec-project] -} diff --git a/fast/stages/2-security/main.tf b/fast/stages/2-security/main.tf index 7d3344762..707990116 100644 --- a/fast/stages/2-security/main.tf +++ b/fast/stages/2-security/main.tf @@ -15,6 +15,25 @@ */ locals { + # additive IAM binding for delegated KMS admins + kms_restricted_admin_template = { + role = "roles/cloudkms.admin" + condition = { + title = "kms_sa_delegated_grants" + description = "Automation service account delegated grants." + expression = format( + <<-EOT + api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s]) && + resource.type == 'cloudkms.googleapis.com/CryptoKey' + EOT + , join(",", formatlist("'%s'", [ + "roles/cloudkms.cryptoKeyEncrypterDecrypter", + "roles/cloudkms.cryptoKeyEncrypterDecrypterViaDelegation" + ])) + ) + } + } + # list of locations with keys kms_locations = distinct(flatten([ for k, v in var.kms_keys : v.locations