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
相关产品推荐
相关产品推荐

