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

Terraform Google Pub/Sub模块:变量未定义与设为null的差异疑问

问题

我在用Terraform部署Google Pub/Sub模块时遇到了问题,模块里的for_each逻辑如下:

for_each = var.create_topic ? { for i in var.push_subscriptions : i.name => i if try(i.dead_letter_topic, "") != "" } : {}

当我传递包含dead_letter_topic = null的push_subscriptions变量时:

push_subscriptions = [
  {
    name                 = "push"
    push_endpoint        = "https://example.com/push"
    dead_letter_topic    = null
  },
]

出现了如下错误:

on .terraform/modules/pubsub/main.tf line 62, in resource "google_pubsub_topic_iam_member" "push_topic_binding":
│   62:   topic   = each.value.dead_letter_topic
│ 
│ The argument "topic" is required, but no definition was found.

但如果完全移除dead_letter_topic字段,代码就能正常运行。我之前以为Terraform会把null视为字段不存在,为什么这两种情况结果不一样?

解决分析
  • null和字段不存在的本质区别:
    Terraform里,null是明确的空值,代表字段存在但无有效值;完全不写字段才是字段不存在。你的try(i.dead_letter_topic, "")逻辑中,字段不存在时会返回默认值"",但如果字段存在且值为null,try会直接返回null。

  • for_each过滤逻辑失效的原因:
    你的过滤条件是try(i.dead_letter_topic, "") != "",当dead_letter_topic = null时,try返回null,而null != ""的结果是true(因为null和任何非null值比较都返回true),所以这个订阅会被纳入for_each集合。但后续google_pubsub_topic_iam_member资源的topic参数要求必须有有效值,传递null就触发了必填参数缺失的错误。

  • 修复方法:
    调整for_each的过滤条件,同时排除null值:

    for_each = var.create_topic ? { 
      for i in var.push_subscriptions : i.name => i 
      if try(i.dead_letter_topic, "") != "" && try(i.dead_letter_topic, null) != null 
    } : {}
    

    或者更简洁的写法,直接检查值是否非空:

    for_each = var.create_topic ? { 
      for i in var.push_subscriptions : i.name => i 
      if !isnull(try(i.dead_letter_topic, null)) && try(i.dead_letter_topic, "") != "" 
    } : {}
    

    这样不管是字段不存在返回默认空字符串,还是字段存在但为null,都会被过滤掉,避免无效的资源创建。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 12:20:50