在 Terraform 0.12 中创建地图时保留列表顺序?
Preserve list ordering when creating maps in Terraform 0.12?
我的配置中有以下片段 - 我的想法是将电流 logic/syntax 从 0.11 更改为 0.12。首先,我从列表创建地图,
my_vars = zipmap(
var.foo_vars,
flatten(data.terraform_remote_state.foo.*.outputs.some_id)
)
然后遍历它以生成一些键值对。
...
"var": [for key in keys(local.my_vars) :
{
name = key
value = lookup(local.my_vars, key)
}
],
...
这里是相关的 tfvars 配置。
foo_vars = [
"A",
"B",
"C"
]
问题是这个逻辑似乎没有保持秩序,我想不出一个好的方法来实现这一点。据我了解,一旦将列表转换为带有 zipmap
的地图,就会重新计算顺序。有什么办法可以保留原始订单吗?
我不受当前解决方案的束缚,所以也许有一种生成 key/values 的方法不需要先创建地图,而只用两个列表即可完成?
~ foo = [
{
name = "A"
value = "1"
},
- {
- name = "B"
- value = "2"
},
{
name = "C"
value = "3"
},
+ {
+ name = "B"
+ valueFrom = "2"
},
]
这里重要的是,正如您所注意到的,Terraform 的地图类型是一种无序地图,它仅通过键而不是权限来标识元素。因此,如果您遇到需要保留序列顺序的情况,那么 map 不是适合使用的数据结构。
我怀疑保持有序可能实际上并不是解决您这里的潜在问题所必需的,但我无法从您分享的信息中看出所有这些的 real-world 含义values 是,所以我将假设您 do 需要保留顺序来回答。如果您使用有序序列只是因为您正在使用 count
创建资源的多个实例,我建议您考虑改用 resource for_each
,这可能会让您解决潜在的问题对 var.foo_vars
.
中的项目顺序不敏感的方式
给定两个长度相同的列表,您可以通过编写 for
expression 来生成一个新列表,该列表组合了每个列表中的相应元素:
locals {
my_vars = [
for i, some_id in data.terraform_remote_state.foo.*.outputs.some_id : {
name = var.foo_vars[i]
value = some_id
}
]
}
以上依赖于一个列表中的 i
索引值与另一个列表中相同索引的元素相关的事实,因此我们可以使用数据中的 i
源实例访问 var.foo_vars
.
的相应元素
我的配置中有以下片段 - 我的想法是将电流 logic/syntax 从 0.11 更改为 0.12。首先,我从列表创建地图,
my_vars = zipmap(
var.foo_vars,
flatten(data.terraform_remote_state.foo.*.outputs.some_id)
)
然后遍历它以生成一些键值对。
...
"var": [for key in keys(local.my_vars) :
{
name = key
value = lookup(local.my_vars, key)
}
],
...
这里是相关的 tfvars 配置。
foo_vars = [
"A",
"B",
"C"
]
问题是这个逻辑似乎没有保持秩序,我想不出一个好的方法来实现这一点。据我了解,一旦将列表转换为带有 zipmap
的地图,就会重新计算顺序。有什么办法可以保留原始订单吗?
我不受当前解决方案的束缚,所以也许有一种生成 key/values 的方法不需要先创建地图,而只用两个列表即可完成?
~ foo = [
{
name = "A"
value = "1"
},
- {
- name = "B"
- value = "2"
},
{
name = "C"
value = "3"
},
+ {
+ name = "B"
+ valueFrom = "2"
},
]
这里重要的是,正如您所注意到的,Terraform 的地图类型是一种无序地图,它仅通过键而不是权限来标识元素。因此,如果您遇到需要保留序列顺序的情况,那么 map 不是适合使用的数据结构。
我怀疑保持有序可能实际上并不是解决您这里的潜在问题所必需的,但我无法从您分享的信息中看出所有这些的 real-world 含义values 是,所以我将假设您 do 需要保留顺序来回答。如果您使用有序序列只是因为您正在使用 count
创建资源的多个实例,我建议您考虑改用 resource for_each
,这可能会让您解决潜在的问题对 var.foo_vars
.
给定两个长度相同的列表,您可以通过编写 for
expression 来生成一个新列表,该列表组合了每个列表中的相应元素:
locals {
my_vars = [
for i, some_id in data.terraform_remote_state.foo.*.outputs.some_id : {
name = var.foo_vars[i]
value = some_id
}
]
}
以上依赖于一个列表中的 i
索引值与另一个列表中相同索引的元素相关的事实,因此我们可以使用数据中的 i
源实例访问 var.foo_vars
.