如何在Terraform中遍历嵌套map生成包含所有zone的集合
你遇到的两个问题的核心原因都是Terraform的map遍历语法使用错误:
- 直接
for item in var.my_var.instances遍历map时,item拿到的是map的值(也就是instance01/instance02对应的数组),无法直接获取外层key; - 你把数组类型的
item直接当做新map的key,而Terraform要求map的key必须是字符串类型,所以抛出string required报错。
要获取外层的instance01、instance02这类key,需要在for表达式中同时声明key和value的接收变量,语法为for <key变量名>, <value变量名> in <待遍历map> :。
场景1:set_of_zones为全局所有zone的去重集合
如果你要的是所有实例下所有zone组成的一维去重集合,直接用flatten压平嵌套数组后提取zone即可:
locals { new_map = { some_field = "arbitrary string" set_of_zones = toset(flatten([ for instance in var.my_var.instances : [ for node in instance : node.zone ] ])) } }
生成的local.new_map.set_of_zones是类似["asia-east1-a", "asia-east1-b", ..., "europe-west3-a"]的去重集合。
场景2:set_of_zones为按实例分组的zone集合map
如果你要的是key为instance01/instance02,value为对应实例下zone集合的map,写法如下:
locals { new_map = { some_field = "arbitrary string" set_of_zones = { # 同时接收key(instance_name)和value(节点数组) for instance_name, nodes in var.my_var.instances : instance_name => toset([ for node in nodes : node.zone ]) } } }
生成的结构为:
{ instance01 = ["asia-east1-a", "asia-east1-b", "asia-east1-c", "asia-east2-a"] instance02 = ["europe-west2-a", "europe-west2-b", "europe-west2-c", "europe-west3-a"] }
额外注意
你定义的my_var变量type约束和default值不匹配:type中声明的字段是name和google_bigtable_clusters,但default值的字段是app_name和instances,实际使用时要注意对齐,避免类型校验报错。
内容的提问来源于stack exchange,提问作者red888
相关产品推荐
相关产品推荐

