Terraform 循环:for_each for 元组

发布于 2025-01-10 13:48:05 字数 4153 浏览 0 评论 0原文

参考:原始问题Terraform 循环:for_each

与问题类似,我有一些更改也需要使用相同的方法进行处理。

更改

db_type 的值可以介于这两者之间

db_type = [["CLUSTER", "LAKE"], ["CLUSTER", "LAKE"], ["CLUSTER", "LAKE"]]

OR

db_type = ["CLUSTER", "CLUSTER", "CLUSTER"]

在这种情况下,当我尝试使用相同的示例时(仅对 db_type 进行更改) ,根据解决方案原始问题观察到以下错误

╷
│ Error: Incorrect attribute value type
│
│   on database_users.tf line 143, in resource "user" "user":
│  143:       type = each.value.cluster.db_type[scopes.key]
│     ├────────────────
│     │ each.value.cluster.db_type is tuple with 3 elements
│
│ Inappropriate value for attribute "type": string required.
╵
╷
│ Error: Incorrect attribute value type
│
│   on database_users.tf line 143, in resource "user" "user":
│  143:       type = each.value.cluster.db_type[scopes.key]
│     ├────────────────
│     │ each.value.cluster.db_type is tuple with 3 elements
│
│ Inappropriate value for attribute "type": string required.
╵
╷
│ Error: Incorrect attribute value type
│
│   on database_users.tf line 143, in resource "user" "user":
│  143:       type = each.value.cluster.db_type[scopes.key]
│     ├────────────────
│     │ each.value.cluster.db_type is tuple with 3 elements
│
│ Inappropriate value for attribute "type": string required.

问题:我真正想要什么?我该如何实现这一目标?

  • 如果我要按照上面的说明更改 db_type 的值,结果应该如下
  # mongodbatlas_database_user.user["test_user2-test_cluster2"] will be created
  + resource "mongodbatlas_database_user" "user" {
      + auth_database_name = "admin"
      + aws_iam_type       = "NONE"
      + id                 = (known after apply)
      + ldap_auth_type     = "NONE"
      + password           = (sensitive value)
      + project_id         = "6216f27d3f350c275ea78efb"
      + username           = "test_user2"
      + x509_type          = "NONE"

      + labels {
          + key   = (known after apply)
          + value = (known after apply)
        }

      + roles {
          + collection_name = (known after apply)
          + database_name   = "db_d"
          + role_name       = "readWrite"
        }
      + roles {
          + collection_name = (known after apply)
          + database_name   = "db_e"
          + role_name       = "readWrite"
        }
      + roles {
          + collection_name = (known after apply)
          + database_name   = "db_f"
          + role_name       = "read"
        }

      + scopes {
          + name = "test_cluster2"
          + type = "CLUSTER"
        }
      + scopes {
          + name = "test_cluster2"
          + type = "LAKE"
        }
    }

如果 db_type 的值 = [["CLUSTER", "LAKE"], ["CLUSTER", " LAKE"], ["CLUSTER", "LAKE"]],预期输出应该是

Resource No. 1

username=test_user1
role = {
  db_name=db_a
  role=readWrite
}
role = {
  db_name=db_b
  role=read
}
role = {
  db_name=db_c
  role=readWrite
}
scope = {
  name = test_cluster1
  type = "cluster"
}
scope = {
  name = test_cluster1
  type = "lake"
}

Resource No. 2

username=test_user1
role = {
  db_name=db_d
  role=readWrite
}
role = {
  db_name=db_e
  role=read
}
role = {
  db_name=db_f
  role=readWrite
}
scope = {
  name = test_cluster2
  type = "cluster"
}
scope = {
  name = test_cluster2
  type = "lake"
}
...

如果 db_type = db_type = ["CLUSTER", "CLUSTER", "CLUSTER"]预期输出应该是

Resource No. 1

username=test_user1
role = {
  db_name=db_a
  role=readWrite
}
role = {
  db_name=db_b
  role=read
}
role = {
  db_name=db_c
  role=readWrite
}
scope = {
  name = test_cluster1
  type = "cluster"
}

Resource No. 2

username=test_user1
role = {
  db_name=db_d
  role=readWrite
}
role = {
  db_name=db_e
  role=read
}
role = {
  db_name=db_f
  role=readWrite
}
scope = {
  name = test_cluster2
  type = "cluster"
}
...

Reference: original question Terraform loop : for_each

Similar to the question I have few changes which needs to be processed using the same method as well.

Changes

The value of db_type could be between any of these two

db_type = [["CLUSTER", "LAKE"], ["CLUSTER", "LAKE"], ["CLUSTER", "LAKE"]]

OR

db_type = ["CLUSTER", "CLUSTER", "CLUSTER"]

In this case, when I try to use the same example (changes on db_type only), as per the solution original question following error is observed

╷
│ Error: Incorrect attribute value type
│
│   on database_users.tf line 143, in resource "user" "user":
│  143:       type = each.value.cluster.db_type[scopes.key]
│     ├────────────────
│     │ each.value.cluster.db_type is tuple with 3 elements
│
│ Inappropriate value for attribute "type": string required.
╵
╷
│ Error: Incorrect attribute value type
│
│   on database_users.tf line 143, in resource "user" "user":
│  143:       type = each.value.cluster.db_type[scopes.key]
│     ├────────────────
│     │ each.value.cluster.db_type is tuple with 3 elements
│
│ Inappropriate value for attribute "type": string required.
╵
╷
│ Error: Incorrect attribute value type
│
│   on database_users.tf line 143, in resource "user" "user":
│  143:       type = each.value.cluster.db_type[scopes.key]
│     ├────────────────
│     │ each.value.cluster.db_type is tuple with 3 elements
│
│ Inappropriate value for attribute "type": string required.

Question: What I actually want? How do I achieve that?

  • If I was to change the value of db_type as explained above following should be the outcome
  # mongodbatlas_database_user.user["test_user2-test_cluster2"] will be created
  + resource "mongodbatlas_database_user" "user" {
      + auth_database_name = "admin"
      + aws_iam_type       = "NONE"
      + id                 = (known after apply)
      + ldap_auth_type     = "NONE"
      + password           = (sensitive value)
      + project_id         = "6216f27d3f350c275ea78efb"
      + username           = "test_user2"
      + x509_type          = "NONE"

      + labels {
          + key   = (known after apply)
          + value = (known after apply)
        }

      + roles {
          + collection_name = (known after apply)
          + database_name   = "db_d"
          + role_name       = "readWrite"
        }
      + roles {
          + collection_name = (known after apply)
          + database_name   = "db_e"
          + role_name       = "readWrite"
        }
      + roles {
          + collection_name = (known after apply)
          + database_name   = "db_f"
          + role_name       = "read"
        }

      + scopes {
          + name = "test_cluster2"
          + type = "CLUSTER"
        }
      + scopes {
          + name = "test_cluster2"
          + type = "LAKE"
        }
    }

If the value of db_type = [["CLUSTER", "LAKE"], ["CLUSTER", "LAKE"], ["CLUSTER", "LAKE"]], the Expected Output should be

Resource No. 1

username=test_user1
role = {
  db_name=db_a
  role=readWrite
}
role = {
  db_name=db_b
  role=read
}
role = {
  db_name=db_c
  role=readWrite
}
scope = {
  name = test_cluster1
  type = "cluster"
}
scope = {
  name = test_cluster1
  type = "lake"
}

Resource No. 2

username=test_user1
role = {
  db_name=db_d
  role=readWrite
}
role = {
  db_name=db_e
  role=read
}
role = {
  db_name=db_f
  role=readWrite
}
scope = {
  name = test_cluster2
  type = "cluster"
}
scope = {
  name = test_cluster2
  type = "lake"
}
...

If the value of db_type = db_type = ["CLUSTER", "CLUSTER", "CLUSTER"], the Expected Output should be

Resource No. 1

username=test_user1
role = {
  db_name=db_a
  role=readWrite
}
role = {
  db_name=db_b
  role=read
}
role = {
  db_name=db_c
  role=readWrite
}
scope = {
  name = test_cluster1
  type = "cluster"
}

Resource No. 2

username=test_user1
role = {
  db_name=db_d
  role=readWrite
}
role = {
  db_name=db_e
  role=read
}
role = {
  db_name=db_f
  role=readWrite
}
scope = {
  name = test_cluster2
  type = "cluster"
}
...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

物价感观 2025-01-17 13:48:06

如果我理解正确,最好按以下形式使用 db_users :

  db_users = {
    test_user1 = {      #user
      test_cluster1 = { #cluster
        db_name = ["db_a", "db_b", "db_c"]
        db_role = ["readWrite", "read", "readWrite"]
        db_type = [["CLUSTER"], ["CLUSTER"], ["CLUSTER"]]
      },
      test_cluster2 = {
        db_name = ["db_a", "db_b", "db_c"]
        db_role = ["readWrite", "read", "readWrite"]
        db_type = [["CLUSTER"], ["CLUSTER"], ["CLUSTER"]]
      }
    },
    test_user2 = {
      test_cluster1 = {
        db_name = ["db_d", "db_e", "db_f"]
        db_role = ["readWrite", "readWrite", "read"]
        db_type = [["CLUSTER", "LAKE"], ["CLUSTER", "LAKE"], ["CLUSTER", "LAKE"]]
      },
      test_cluster2 = {
        db_name = ["db_d", "db_e", "db_f"]
        db_role = ["readWrite", "readWrite", "read"]
        db_type = [["CLUSTER"], ["CLUSTER"], ["CLUSTER"]]
      }
    }
  }

然后将其展平为:

  
  db_users_flat = merge(flatten([
    for username, clusters in local.db_users : 
      [
         for clustername, cluster in clusters : 
         {
             for idx, db_types in cluster.db_type: 
                 "${username}-${clustername}-${idx}" => {
                       username = username
                       clustername = clustername
                       cluster = {
                         db_name = cluster.db_name
                         db_role = cluster.db_role
                         db_type = db_types
                       }
                  }
               }
       ]
  ])...)

并使用为:

resource "users" "user" {
    for_each = local.db_users_flat
    username = each.value.username
    dynamic "roles" {
      for_each = range(length(each.value.cluster.db_name))
      content {
        database_name = each.value.cluster.db_name[roles.key]
        role_name     = each.value.cluster.db_role[roles.key]
      }
    }
    dynamic "scopes" {
      for_each = range(length(each.value.cluster.db_type))
      content {
        name = each.value.clustername
        type = each.value.cluster.db_type[scopes.key]
      }
    }
}

If I understand correctly, its better to use db_users in the following form:

  db_users = {
    test_user1 = {      #user
      test_cluster1 = { #cluster
        db_name = ["db_a", "db_b", "db_c"]
        db_role = ["readWrite", "read", "readWrite"]
        db_type = [["CLUSTER"], ["CLUSTER"], ["CLUSTER"]]
      },
      test_cluster2 = {
        db_name = ["db_a", "db_b", "db_c"]
        db_role = ["readWrite", "read", "readWrite"]
        db_type = [["CLUSTER"], ["CLUSTER"], ["CLUSTER"]]
      }
    },
    test_user2 = {
      test_cluster1 = {
        db_name = ["db_d", "db_e", "db_f"]
        db_role = ["readWrite", "readWrite", "read"]
        db_type = [["CLUSTER", "LAKE"], ["CLUSTER", "LAKE"], ["CLUSTER", "LAKE"]]
      },
      test_cluster2 = {
        db_name = ["db_d", "db_e", "db_f"]
        db_role = ["readWrite", "readWrite", "read"]
        db_type = [["CLUSTER"], ["CLUSTER"], ["CLUSTER"]]
      }
    }
  }

then you flatten as:

  
  db_users_flat = merge(flatten([
    for username, clusters in local.db_users : 
      [
         for clustername, cluster in clusters : 
         {
             for idx, db_types in cluster.db_type: 
                 "${username}-${clustername}-${idx}" => {
                       username = username
                       clustername = clustername
                       cluster = {
                         db_name = cluster.db_name
                         db_role = cluster.db_role
                         db_type = db_types
                       }
                  }
               }
       ]
  ])...)

and use as:

resource "users" "user" {
    for_each = local.db_users_flat
    username = each.value.username
    dynamic "roles" {
      for_each = range(length(each.value.cluster.db_name))
      content {
        database_name = each.value.cluster.db_name[roles.key]
        role_name     = each.value.cluster.db_role[roles.key]
      }
    }
    dynamic "scopes" {
      for_each = range(length(each.value.cluster.db_type))
      content {
        name = each.value.clustername
        type = each.value.cluster.db_type[scopes.key]
      }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文