引用:original question Terraform loop : for_each
与问题类似,我有一些更改也需要使用相同的方法进行处理。
更改
db_type
的值可以介于这两者之间
db_type = [["CLUSTER", "LAKE"], ["CLUSTER", "LAKE"], ["CLUSTER", "LAKE"]]
OR
db_type = ["CLUSTER", "CLUSTER", "CLUSTER"]
在这种情况下,当我尝试使用相同的示例时(仅对 db_type 进行更改),按照 solution original question 观察到以下错误
╷
│ 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"]]
,则 < strong>预期输出应该是
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"
}
...
最佳答案
如果我理解正确的话,最好使用以下形式的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]
}
}
}
关于Terraform循环: for_each for tuple,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71293523/