- OpenTofu 语言
- 函数
- flatten
flatten
函数
flatten
接收一个列表,并将列表中任何元素(如果为列表)替换为列表内容的扁平化序列。
示例
> flatten([["a", "b"], [], ["c"]])
["a", "b", "c"]
如果任何嵌套列表也包含直接嵌套的列表,这些列表也会递归地扁平化。
> flatten([[["a", "b"], []], ["c"]])
["a", "b", "c"]
间接嵌套的列表(例如地图中的列表)不会被扁平化。
为 for_each
扁平化嵌套结构
资源 for_each
和 dynamic
块 语言功能都要求一个集合值,该值对每次重复都有一个元素。
有时你的输入数据结构不能自然地以适合在 for_each
参数中使用的形状出现,而 flatten
在将嵌套数据结构简化为扁平结构时可能是一个有用的辅助函数。
例如,考虑一个声明以下变量的模块
variable "networks" {
type = map(object({
cidr_block = string
subnets = map(object({ cidr_block = string }))
}))
}
以上是为自然形成树状结构的对象(如顶级网络及其子网)建模的一种合理方式。顶级网络的重复可以直接使用此变量,因为它已经是这样一种形式:结果实例与地图元素一一对应。
resource "aws_vpc" "example" {
for_each = var.networks
cidr_block = each.value.cidr_block
}
但是,为了用单个 resource
块声明所有子网,我们必须首先扁平化结构,以生成一个集合,其中每个顶级元素都代表一个子网。
locals {
# flatten ensures that this local value is a flat list of objects, rather
# than a list of lists of objects.
network_subnets = flatten([
for network_key, network in var.networks : [
for subnet_key, subnet in network.subnets : {
network_key = network_key
subnet_key = subnet_key
network_id = aws_vpc.example[network_key].id
cidr_block = subnet.cidr_block
}
]
])
}
resource "aws_subnet" "example" {
# local.network_subnets is a list, so we must now project it into a map
# where each key is unique. We'll combine the network and subnet keys to
# produce a single unique key per instance.
for_each = {
for subnet in local.network_subnets : "${subnet.network_key}.${subnet.subnet_key}" => subnet
}
vpc_id = each.value.network_id
availability_zone = each.value.subnet_key
cidr_block = each.value.cidr_block
}
以上结果是每个子网对象一个子网实例,同时保留子网与其包含的网络之间的关联。
相关函数
setproduct
查找多个列表或值集的所有组合,这在为使用for_each
结构准备集合时也很有用。