/** * Copyright 2025 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ # tfdoc:file:description Service Agent IAM Bindings for CMEK locals { # list of service agents per product that need to be granted # cryptoKeyEncrypterDecrypter to use CMEK. # https://cloud.google.com/kms/docs/compatible-services # TODO: extend to support dependencies for all products _cmek_agents_by_service = { "aiplatform.googleapis.com" : ["aiplatform"] "alloydb.googleapis.com" : ["alloydb"] "artifactregistry.googleapis.com" : ["artifactregistry"] "bigtableadmin.googleapis.com" : ["bigtable"] "bigquery.googleapis.com" : ["bigquery-encryption"] # the list for composer now tracks composer 3 # https://cloud.google.com/composer/docs/composer-3/configure-cmek-encryption#grant-roles-permissions "composer.googleapis.com" : ["composer", "storage"] "compute.googleapis.com" : ["compute"] "container.googleapis.com" : ["compute", "container-engine-robot"] "dataflow.googleapis.com" : ["dataflow", "compute"] "dataform.googleapis.com" : ["dataform"] "datafusion.googleapis.com" : [ "datafusion", "compute", "storage", "dataproc", "pubsub", "spanner" # these 2 are optional ] "dataproc.googleapis.com" : ["dataproc"] "datastream.googleapis.com" : ["datastream"] "dialogflow.googleapis.com" : ["dialogflow-cmek"] "file.googleapis.com" : ["cloud-filer"] "logging.googleapis.com" : ["logging"] "pubsub.googleapis.com" : ["pubsub"] "run.googleapis.com" : ["cloudrun"] "secretmanager.googleapis.com" : ["secretmanager"] "spanner.googleapis.com" : ["spanner"] "sqladmin.googleapis.com" : ["cloud-sql"] "storage.googleapis.com" : ["storage"] } _all_cmek_bindings = flatten([ for service, keys in var.service_encryption_key_ids : [ for dep in try( local._cmek_agents_by_service[service], [for x in local.service_agents_by_api[service] : x.name], [service] ) : [ for key in keys : { key_id = key agent_name = local.aliased_service_agents[dep].name agent_email = local.aliased_service_agents[dep].iam_email } ] ] ]) _cmek_bindings_grouped_by_agent = { for binding in local._all_cmek_bindings : binding.agent_name => binding... } _cmek_members = merge([ for agent_name, bindings in local._cmek_bindings_grouped_by_agent : { for i, binding in bindings : "key-${i}.${agent_name}" => { key = binding.key_id agent = binding.agent_email } } ]...) } resource "google_kms_crypto_key_iam_member" "service_agent_cmek" { for_each = local._cmek_members crypto_key_id = lookup(local.ctx.kms_keys, each.value.key, each.value.key) role = "roles/cloudkms.cryptoKeyEncrypterDecrypter" member = each.value.agent depends_on = [ google_project.project, google_project_service.project_services, google_project_service_identity.default, google_project_iam_member.service_agents, data.google_project.project, data.google_bigquery_default_service_account.bq_sa, data.google_storage_project_service_account.gcs_sa, data.google_logging_project_settings.logging_sa ] }