Terraform中嵌套for_each为google_project_iam_binding分配成员遇阻
解决方案
问题核心
你的问题根源在于:
google_logging_project_sink.instance-sink是通过for_each生成的资源映射(map),无法直接通过资源名访问属性,必须指定具体实例键google_project_iam_binding.log-writer按角色做for_each,需要将所有sink的writer_identity批量加入对应角色的成员列表
具体修改方案
1. 修复日志Sink的目标地址错误
原配置中sink的destination使用了[0]索引,但google_logging_project_bucket_config.custom_log_bucket是for_each生成的映射,需用each.key匹配对应bucket实例:
resource "google_logging_project_sink" "instance-sink" { for_each = var.cross_project_logsink_service name = format("%s_logsink_%s", var.domain, each.key) description = "log sink from ${local.monitored_resource_project[each.key]}" # 用each.key匹配对应bucket实例 destination = "logging.googleapis.com/${google_logging_project_bucket_config.custom_log_bucket[each.key].id}" filter = "resource.type=cloud_composer_environment" project = local.monitored_resource_project[each.key] unique_writer_identity = true }
2. 为IAM Binding批量添加所有Sink的Writer Identity
使用for表达式遍历所有sink实例,收集它们的writer_identity作为成员列表:
resource "google_project_iam_binding" "log-writer" { for_each = toset([ "roles/storage.objectCreator", "roles/logging.bucketWriter" ]) project = var.monitoring_project role = each.key # 遍历所有sink实例,收集writer_identity members = [for sink in google_logging_project_sink.instance-sink : sink.writer_identity] }
可选:细粒度IAM绑定(角色+Sink独立绑定)
如果需要为每个角色单独绑定单个sink的身份(而非批量绑定所有),可以用setproduct生成角色与sink键的笛卡尔积,实现双重for_each:
# 生成角色与sink键的组合集合 locals { role_sink_combinations = setproduct( ["roles/storage.objectCreator", "roles/logging.bucketWriter"], var.cross_project_logsink_service ) } resource "google_project_iam_binding" "log-writer" { # 用笛卡尔积作为for_each的键,每个元素是[角色, sink键]的元组 for_each = { for combo in local.role_sink_combinations : "${combo[0]}-${combo[1]}" => combo } project = var.monitoring_project role = each.value[0] # 匹配对应的sink实例 members = [ google_logging_project_sink.instance-sink[each.value[1]].writer_identity ] }
验证
修改后执行terraform plan,即可正确识别所有资源依赖,解决"Missing resource instance key"错误。
内容的提问来源于stack exchange,提问作者adithyar24200
相关产品推荐
相关产品推荐

