如何用Terraform构建Kubernetes服务所需的日志服务映射列表?
解决Terraform生成K8s服务端口-协议映射的问题
问题分析
你需要将两种格式的输入变量(列表/映射),转换为以服务名为键,每个键对应一组单端口+单协议的条目列表,用于创建Kubernetes服务。之前的locals配置仅生成了扁平化的条目列表,未完成按服务名分组及结构转换。
针对列表类型变量(elk_services1)的解决方案
使用Terraform的for表达式先生成所有端口-协议的组合条目,再按服务名分组:
locals { # 第一步:生成所有端口与协议的笛卡尔积条目 svc_entries = flatten([ for svc in var.elk_services1 : [ for port in svc.ports : [ for proto in svc.protocol : { name = svc.name port = port protocol = proto namespace = svc.namespace } ] ] ]) # 第二步:按服务名分组,转换为期望的结构 svc_mapping = { for entry in local.svc_entries : entry.name => [ for e in local.svc_entries : { ports = [e.port] protocol = [e.protocol] namespace = e.namespace } if e.name == entry.name ]... } }
针对映射类型变量(elk_services2)的解决方案
映射类型变量的遍历只需增加键的提取,逻辑与列表类型一致:
locals { # 第一步:生成所有端口与协议的笛卡尔积条目 svc_entries2 = flatten([ for svc_key, svc in var.elk_services2 : [ for port in svc.ports : [ for proto in svc.protocol : { name = svc.name port = port protocol = proto namespace = svc.namespace } ] ] ]) # 第二步:按服务名分组,转换为期望的结构 svc_mapping2 = { for entry in local.svc_entries2 : entry.name => [ for e in local.svc_entries2 : { ports = [e.port] protocol = [e.protocol] namespace = e.namespace } if e.name == entry.name ]... } }
关键说明
flatten用于将嵌套的列表结构扁平化,方便后续分组for表达式后的...是Terraform的分组操作符,会将相同键的元素合并为列表- 最终输出的每个条目严格匹配你期望的格式:
ports和protocol均为单元素列表,保留namespace信息
内容的提问来源于stack exchange,提问作者JonLinux
相关产品推荐
相关产品推荐

