You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Terraform中如何在for_each循环内排除指定子网?

Terraform 0.14 使用 regexall 过滤 for_each 子网对象的解决方案

问题场景

我用hashicorp/subnets/cidr模块生成了一批子网对象列表,需要通过for_each遍历这些子网创建google_compute_global_address资源,但得排除名称以not-in-use开头的子网。

一开始我写了这样的代码:

for_each = {for subnet in module.regions.networks: subnet.name => subnet if regexall("^in-use", subnet.name)}

结果直接报错:

Error: Invalid 'for' condition
The 'if' clause value is invalid: bool required.

哪怕把regexall()套在length()里也没解决问题。

注:虽然startswith()是处理前缀匹配更合适的函数,但我用的是Terraform 0.14版本,这个函数还没推出,只能继续用regexall(),最后加个>0就搞定了。

错误原因

Terraform的for表达式里,if子句必须返回布尔值(true/false),但regexall()的返回值是匹配结果的列表,不是布尔值,直接用它当条件就会触发类型不匹配的错误。之前用length()没生效,大概率是写法不对——得明确判断列表长度是否大于0,把列表结果转成布尔值才行。

解决方法

调整for_each的表达式,通过length(regexall(...)) > 0把正则匹配结果转换成布尔条件,就能符合if子句的要求了。

匹配以in-use开头的子网(保留这类子网)

for_each = {
  for subnet in module.regions.networks : subnet.name => subnet
  if length(regexall("^in-use", subnet.name)) > 0
}

排除以not-in-use开头的子网(符合最初需求)

如果你的目标是排除前缀为not-in-use的子网,对应的正则和条件要改成这样:

for_each = {
  for subnet in module.regions.networks : subnet.name => subnet
  if length(regexall("^not-in-use", subnet.name)) == 0
}

另一种简洁写法

Terraform会把非空列表隐式转为true,空列表转为false,所以也可以这么写(不过显式判断长度的写法可读性更强):

for_each = {
  for subnet in module.regions.networks : subnet.name => subnet
  if regexall("^in-use", subnet.name) != []
}

内容的提问来源于stack exchange,提问作者red888

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 14:48:24