You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Terraform嵌套Map分配GCS IAM权限时出现错误求助

解决Terraform配置GCP存储桶IAM权限的嵌套Map错误

问题场景

尝试通过Terraform为不同成员分配GCP存储桶的IAM角色,采用嵌套Map逻辑实现,但因使用两个变量构建资源,导致逻辑出错。

原代码

main.tf

locals {
 
  data_access = flatten([
    for bkt_key, bkt_value in var.buckets_data : [
      for user,roles in var.data_access : [
        for role in roles:{
        member = user
        bkt  = bkt_key
        role   = roles
      }]
    ]
  ])
}

resource "google_storage_bucket_iam_member" "buckets_data_access" {
  for_each = { for access in local.data_access : "${access.bkt}_${access.member}" => access... }
  bucket   = google_storage_bucket.tf_buckets_data[each.value.bkt].name
  role     = each.value.role
  member   = each.value.member
}

terraform.tfvars

buckets_data = {
  "landing" = { 
    region          = "nane1",
    storage_class   = "COLDLINE",
    versioning      = "false",
    data_tier       = "raw",
    lifecycle_rules = ["retention-2years"],
    external_access = []
  },
  "dftemp" = {
    region          = "nane1",
    storage_class   = "STANDARD"
  },
  "curated" = {
    region          = "nane1",
    storage_class   = "STANDARD"
  }
}

data_access = {
  "group:GCP-npe@bell.ca" = ["roles/storage.objectViewer","roles/Browser"]
}

错误信息

$ terraform plan
╷
│ Error: Unsupported attribute
│
│   on main.tf line 29, in resource "google_storage_bucket_iam_member" "buckets_data_access":
│   29:   bucket   = google_storage_bucket.tf_buckets_data[each.value.bkt].name
│     ├────────────────
│     │ each.value is tuple with 2 elements
│
│ This value does not have any attributes.
╵
╷
│ Error: Unsupported attribute
│
│   on main.tf line 29, in resource "google_storage_bucket_iam_member" "buckets_data_access":
│   29:   bucket   = google_storage_bucket.tf_buckets_data[each.value.bkt].name
│     ├────────────────
│     │ each.value is tuple with 2 elements
│
│ This value does not have any attributes.
╵
╷
│ Error: Unsupported attribute
│
│   on main.tf line 30, in resource "google_storage_bucket_iam_member" "buckets_data_access":
│   30:   role     = each.value.role
│     ├────────────────
│     │ each.value is tuple with 2 elements
│
│ This value does not have any attributes.
╵
╷
│ Error: Unsupported attribute
│
│   on main.tf line 30, in resource "google_storage_bucket_iam_member" "buckets_data_access":
│   30:   role     = each.value.role
│     ├────────────────
│     │ each.value is tuple with 2 elements
│
│ This value does not have any attributes.
╵
╷
│ Error: Unsupported attribute
│
│   on main.tf line 31, in resource "google_storage_bucket_iam_member" "buckets_data_access":
│   31:   member   = each.value.member
│     ├────────────────
│     │ each.value is tuple with 2 elements
│
│ This value does not have any attributes.
╵
╷
│ Error: Unsupported attribute
│
│   on main.tf line 31, in resource "google_storage_bucket_iam_member" "buckets_data_access":
│   31:   member   = each.value.member
│     ├────────────────
│     │ each.value is tuple with 2 elements
│
│ This value does not have any attributes.

错误原因

  1. 内层循环赋值错误:在for role in roles循环中,错误地将role字段赋值为整个角色列表roles,导致每个条目包含的是角色列表而非单个角色。
  2. for_each键重复+展开操作错误:仅用${access.bkt}_${access.member}作为键,无法区分同一桶和成员下的不同角色;同时使用access...展开元组,导致each.value变成元组而非预期的对象,自然无法访问.bkt、.role等属性。

修正后的代码

main.tf

locals {
  data_access = flatten([
    for bkt_key, bkt_value in var.buckets_data : [
      for user, roles in var.data_access : [
        for role in roles : {
          member = user
          bkt    = bkt_key
          role   = role  # 改为单个角色值,而非整个角色列表
        }
      ]
    ]
  ])
}

resource "google_storage_bucket_iam_member" "buckets_data_access" {
  # 加入role信息生成唯一键,替换斜杠避免非法字符
  for_each = {
    for access in local.data_access : 
    "${access.bkt}_${access.member}_${replace(access.role, "/", "_")}" => access
  }
  
  bucket   = google_storage_bucket.tf_buckets_data[each.value.bkt].name
  role     = each.value.role
  member   = each.value.member
}

修正说明

  • 调整内层循环的role赋值,确保每个条目对应单个成员-单个桶-单个角色的组合,符合google_storage_bucket_iam_member资源的要求(每个资源实例对应一个IAM绑定关系)。
  • 重构for_each的键生成逻辑,加入角色信息并替换斜杠为下划线,保证每个资源实例的键唯一,避免同一桶和成员下多角色导致的冲突。
  • 移除access...的展开操作,直接使用单个对象作为each.value,确保可以正常访问.bkt、.role、.member属性。

内容的提问来源于stack exchange,提问作者adithyar24200

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 23:50:23