Terraform 循环:for_each 元组
Terraform loop : for_each for tuple
参考:
与问题类似,我也有一些更改需要使用相同的方法进行处理。
变化
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"
}
...
如果我没理解错的话,最好用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]
}
}
}
参考:
与问题类似,我也有一些更改需要使用相同的方法进行处理。
变化
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"
}
...
如果我没理解错的话,最好用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]
}
}
}