Terraform创建GCP Gen2云函数AuditLog触发器遇PubSub加密问题
解决方法
问题核心在于:AuditLog类型的云函数触发器会自动创建未加密的PubSub Topic,而组织策略禁止此类资源;同时AuditLog触发器不支持手动指定自定义Topic。解决思路是手动搭建完整的事件链路,绕开自动创建的未加密资源:
步骤1:创建CMEK加密的PubSub Topic
先手动创建使用指定KMS密钥加密的PubSub Topic,确保符合组织策略要求。
步骤2:配置AuditLog Sink路由事件到加密Topic
创建日志Sink,将Secret Manager的CreateSecret事件定向到刚才创建的加密Topic,同时给Sink的服务账号授予Topic的发布权限。
步骤3:创建Gen2云函数并关联PubSub触发器
将云函数的触发器类型改为标准的PubSub消息触发,关联之前创建的加密Topic,这样就不会自动生成未加密资源。
Terraform代码示例
# 引用已有的KMS密钥(如果还没有,需先创建密钥环和密钥) data "google_kms_crypto_key" "secret_audit_key" { name = "your-cmek-key-name" key_ring = "your-key-ring-name" location = "us-central1" # 与资源区域一致 } # 创建CMEK加密的PubSub Topic resource "google_pubsub_topic" "secret_audit_topic" { name = "secret-creation-audit-topic" kms_key_name = data.google_kms_crypto_key.secret_audit_key.id } # 配置Secret Manager的AuditLog记录 resource "google_project_audit_config" "secret_manager_audit" { project = var.gcp_project_id service = "secretmanager.googleapis.com" audit_log_config { log_type = "DATA_WRITE" exempted_members = [] } } # 创建日志Sink,路由CreateSecret事件到加密Topic resource "google_logging_project_sink" "secret_audit_sink" { name = "secret-creation-audit-sink" destination = "pubsub.googleapis.com/${google_pubsub_topic.secret_audit_topic.id}" filter = "resource.type=\"secretmanager.googleapis.com/Secret\" AND protoPayload.methodName=\"google.cloud.secretmanager.v1.SecretManagerService.CreateSecret\"" unique_writer_identity = true } # 给Sink服务账号授予PubSub Topic发布权限 resource "google_pubsub_topic_iam_binding" "sink_publish_permission" { topic = google_pubsub_topic.secret_audit_topic.name role = "roles/pubsub.publisher" members = [ google_logging_project_sink.secret_audit_sink.writer_identity, ] } # 创建Gen2云函数,使用PubSub触发器 resource "google_cloudfunctions2_function" "secret_audit_function" { name = "secret-creation-audit-function" location = "us-central1" description = "Triggered when a new GCP Secret is created" build_config { runtime = "nodejs20" # 替换为你的函数运行时 entry_point = "handleSecretCreation" # 替换为你的函数入口 source { storage_source { bucket = "your-function-source-bucket" # 替换为存储函数代码的GCS桶 object = "function-code.zip" # 替换为你的函数代码压缩包路径 } } } service_config { max_instance_count = 1 available_memory = "256MiB" timeout_seconds = 60 } event_trigger { trigger_region = "us-central1" event_type = "google.cloud.pubsub.topic.v1.messagePublished" pubsub_topic = google_pubsub_topic.secret_audit_topic.id retry_policy { retry_all = true } } }
关键注意事项
- KMS权限配置:确保PubSub服务账号(
service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com)拥有KMS密钥的cloudkms.cryptoKeyEncrypterDecrypter权限,否则Topic无法正常使用CMEK加密。 - 日志Filter准确性:确认filter只捕获你需要的
CreateSecret事件,避免多余消息触发函数。 - 资源区域一致性:确保KMS密钥、PubSub Topic、云函数在同一GCP区域,避免跨区域的权限或延迟问题。
内容的提问来源于stack exchange,提问作者Cole Gulledge
相关产品推荐
相关产品推荐

