在我的配置中,我有以下代码片段-想法是将当前逻辑/语法从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
的地图,订单就会重新计算。有什么办法可以保留原始订单?
我不受当前解决方案的束缚,所以也许有一种生成键/值的方法,而该键/值不需要先创建映射就可以只用两个列表来完成?
~ foo = [
{
name = "A"
value = "1"
},
- {
- name = "B"
- value = "2"
},
{
name = "C"
value = "3"
},
+ {
+ name = "B"
+ valueFrom = "2"
},
]
答案 0 :(得分:1)
这里重要的是,正如您所注意到的,Terraform的地图类型是无序地图,它仅通过元素的键而不是许可来标识元素。因此,如果遇到需要保留序列顺序的情况,则映射不适合使用数据结构。
我怀疑保持秩序井然并不是解决这里潜在问题的必要方法,但是我无法从您共享的信息中看出所有这些值的真实含义,所以我将假设您要做需要保留订单。如果仅由于使用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
的相应元素。