Terraform遍历嵌套列表时遭遇null值迭代错误,求排查
Terraform迭代null值问题排查
输入变量
appr = { "product1" = {WO = ["6470"], RO = ["6471","5538"]}, "product2" = {RO = ["6472"]} }
错误信息
│ Error: Iteration over null value │ │ on ../../modules/sa_pc/main.tf line 15, in locals: │ 14: for co, coo in clsan : [ │ 15: for applo in coo : [ │ 16: for op in ( co == "RO" ? ["READ","DESCRIBE"] : ["WRITE"] ) : { │ 17: oper = op │ 18: │ 19: appid_lo = applo │ 20: opic-name = opi │ 21: process = co │ 22: } │ 23: ] │ 24: ] │ │ A null value cannot be used as the collection in a 'for' expression.
问题描述
执行terraform plan时提示coo为null值无法迭代,但在terraform console中能得到预期输出。coo是通过for循环遍历的列表。
已尝试的代码
locals { acl_out = flatten([ for opi, clsan in var.appr : [ for co, coo in clsan : [ for applo in coo : [ for op in ( co == "RO" ? ["READ","DESCRIBE"] : ["WRITE"]) : { oper = op appid_lo = applo opic-name = opi process = co } ] ] ] ]) }
问题原因
核心差异在于Terraform的静态类型检查和动态运行计算的区别:
terraform plan会做静态类型推断,由于输入变量未显式约束类型,它会认为var.appr的结构允许某个操作类型(比如WO/RO)对应的值为null,因此提前检测到潜在的null迭代风险并报错。terraform console基于当前输入的实际值动态计算,当前输入里没有null值,所以能正常输出结果。
解决方案
方案1:过滤null值
在遍历coo前先判断是否为null,仅处理非null的情况:
locals { acl_out = flatten([ for opi, clsan in var.appr : [ for co, coo in clsan : coo != null ? [ for applo in coo : [ for op in (co == "RO" ? ["READ", "DESCRIBE"] : ["WRITE"]) : { oper = op appid_lo = applo opic-name = opi process = co } ] ] : [] ] ]) }
方案2:默认空列表兜底
用try()函数给coo设置默认空列表,确保永远是可迭代的集合:
locals { acl_out = flatten([ for opi, clsan in var.appr : [ for co, coo in clsan : [ for applo in try(coo, []) : [ for op in (co == "RO" ? ["READ", "DESCRIBE"] : ["WRITE"]) : { oper = op appid_lo = applo opic-name = opi process = co } ] ] ]) }
额外优化:显式约束变量类型
如果能确定var.appr的结构中,WO/RO的值永远是列表(不会为null),可以给变量添加显式类型约束,从根源避免类型推断的问题:
variable "appr" { type = map(object({ WO = optional(list(string), []) RO = optional(list(string), []) })) }
内容的提问来源于stack exchange,提问作者Nabob
相关产品推荐
相关产品推荐

