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

如何用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 03:05:58