Terraform动态块如何适配多URI列表并过滤空值
实现方法
1. 更新变量定义
先修改services变量的结构,把uri字段从可选字符串改为可选字符串列表,默认设为空列表方便后续过滤:
variable "services" { type = map(object({ # 保留原有其他字段,比如服务名、端口等 service_name = string port = number uri = optional(list(string), []) # 改为列表类型,默认空列表 })) }
2. 预处理生成规则条目
在Ingress资源定义前,通过flatten和for表达式把服务与对应URI展开成扁平条目集合,同时自动过滤掉URI为空列表的服务:
locals { ingress_rules = flatten([ for service_key, service in var.services : [ for uri in service.uri : { service_key = service_key uri = uri service = service } ] if length(service.uri) > 0 # 过滤无有效URI的服务 ]) }
这个本地值会把每个服务的每个URI拆成独立条目——比如一个服务配置3个URI,就生成3个条目;没有URI或URI为空的服务会直接被跳过。
3. 用动态块生成Ingress规则
在Kubernetes Ingress资源的rules块中,结合dynamic和for_each遍历预处理后的ingress_rules,为每个URI生成一条独立规则:
resource "kubernetes_ingress_v1" "example" { metadata { name = "example-ingress" annotations = { # 按需添加Ingress注解,比如路径重写规则等 } } spec { ingress_class_name = "nginx" # 根据你的Ingress Class调整 dynamic "rule" { # 用服务key+URI生成唯一键,避免Terraform因重复键报错 for_each = { for r in local.ingress_rules : "${r.service_key}_${r.uri}" => r } content { host = "example.com" # 按需设置域名 http { path { path = rule.value.uri path_type = "Prefix" # 按需设置路径类型,比如Exact/Prefix backend { service { name = rule.value.service.service_name port { number = rule.value.service.port } } } } } } } } }
关键说明
for_each用"${r.service_key}_${r.uri}"作为唯一标识,确保每个规则条目唯一,符合Terraform的要求。if length(service.uri) > 0的判断逻辑,自动跳过没有配置有效URI的服务。- 如果需要支持多域名,可以把
host字段加入services对象的定义中,在预处理和动态块中对应引用即可。
内容的提问来源于stack exchange,提问作者Lucas Cañero
相关产品推荐
相关产品推荐

