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

Terraform配置kubernetes_network_policy条件渲染CIDR块报错排查

问题根因
  • Terraform 不支持直接在资源块内用三元表达式控制嵌套块(比如代码里的from/to块)的显隐,这种写法不符合HCL语法规范,所以会触发Argument or block definition required报错。
  • Terraform 中嵌套块的条件渲染必须通过dynamic块实现,通过控制dynamic块的for_each值为空集合/非空集合,来决定是否生成目标嵌套块。
  • 原始代码还存在3处逻辑错误:
    • dynamic "ingress"的for_each判断条件写错,误判each.value.egress_number == null,实际应该判断each.value.ingress_number
    • egress块内的CIDR判断误引用了var.ingress_to_cidr,实际应该匹配egress对应的CIDR参数
    • 直接对可能为null的参数调用length()会触发运行时报错,需要先做非空判断
  • 之前遇到的failed to expand IPBlock: null or empty input错误,本质是CIDR参数为空时仍然渲染了ip_block块传入空值,Kubernetes Provider无法解析空的IPBlock配置。
正确实现方案

对ingress下的from块、egress下的to块分别定义独立的dynamic块:

  • 当对应CIDR参数为非空有效值时,for_each赋值为长度1的列表,渲染1次对应的from/to+ip_block块
  • 当对应CIDR参数为null或空字符串时,for_each赋值为空列表,完全不渲染对应块,从根源避免空IPBlock报错

修正后的完整代码如下:

resource "kubernetes_network_policy" "example-policy" {
  for_each = var.inputs
  metadata {
    name      = each.value.name
    namespace = each.value.namespace
  }
  spec {
    pod_selector {
      match_labels = {
        app = each.value.selector
      }
    }
    policy_types = each.value.policy

    dynamic "ingress" {
      # 修正原错误的判断条件,匹配ingress规则参数
      for_each = each.value.ingress_number == null ? [] : range(length(each.value.ingress_number))
      content {
        ports {
          port     = each.value.ingress_number[ingress.value]
          protocol = each.value.ingress_protocol[ingress.value]
        }

        # 用dynamic块控制from块按需渲染
        dynamic "from" {
          # 仅当ingress_to_cidr为非空有效值时生成块
          for_each = each.value.ingress_to_cidr != null && length(trimspace(each.value.ingress_to_cidr)) > 0 ? [1] : []
          content {
            ip_block {
              cidr = each.value.ingress_to_cidr
            }
          }
        }
      }
    }

    dynamic "egress" {
      for_each = each.value.egress_number == null ? [] : range(length(each.value.egress_number))
      content {
        ports {
          port     = each.value.egress_number[egress.value]
          protocol = each.value.egress_protocol[egress.value]
        }

        # 用dynamic块控制to块按需渲染
        dynamic "to" {
          # 修正原错误的变量引用,匹配egress规则的CIDR参数
          for_each = each.value.egress_to_cidr != null && length(trimspace(each.value.egress_to_cidr)) > 0 ? [1] : []
          content {
            ip_block {
              cidr = each.value.egress_to_cidr
            }
          }
        }
      }
    }
  }
}
效果说明
  • 执行terragrunt plan和terragrunt apply时,未传入有效CIDR的规则不会生成from/to下的ip_block块,不会触发空IPBlock解析错误
  • 传入有效CIDR时会正常渲染对应配置块,符合按需渲染的需求
  • 修正了原代码中变量引用错误、条件判断错位的逻辑问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 21:39:29