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

如何用Terraform为Ingress自动配置多后端服务

问题描述

我正在通过Terraform的Helm Provider部署GKE集群与2个测试应用,这两个应用会输出自定义消息,期望Nginx Ingress能根据路径前缀转发至对应服务。目前手动将各Release的服务名添加到Ingress规则/后端可正常运行,但希望在执行terraform apply时自动完成该配置:部署Release与Ingress后,自动获取可用的服务名并传入Ingress,这样后续新增10个不同路径的Release时,只需在变量映射中添加配置即可。请问是否可行?能否像Terraform中那样将输出传递给变量?以下是我的Helm资源配置、releases_map变量配置及Ingress模板,希望通过Terraform覆盖values.yaml中的值来实现需求。

现有Helm资源配置

resource "helm_release" "helm_releases" {
  for_each         = var.releases_map
  name             = each.key
  chart            = each.value.chart_source
  namespace        = each.value.namespace
  create_namespace = each.value.create_namespace

  values = [
    "${file("./helm-app/values.yaml")}"
  ]

  set {
    name  = "deployment.replicaCount"
    value = each.value.replica_count
  }
  .
  .
}

releases_map变量配置

releases_map = {
  "gke-test-1" = {
    chart_source     = "./helm-app"
    namespace        = "gke-ns"
    create_namespace = true
    service_type     = "ClusterIP"
    replica_count    = "3"
    service_port     = "80"
    container_image  = "publicrepo/helm-app"
    image_version    = "1.10"
    ingress_configured = true
    path_prefix        = "/custom-message-1"
    message          = "test-1"
  }
  "gke-test-2" = {
    chart_source     = "./helm-app"
    namespace        = "gke-ns"
    create_namespace = false
    service_type     = "ClusterIP"
    replica_count    = "3"
    service_port     = "80"
    container_image  = "publicrepo/helm-app"
    image_version    = "1.10"
    ingress_configured = true
    path_prefix        = "/custom-message-2"
    message          = "test-2"
  }
}

Ingress模板(helm-app/templates/ingress.yaml)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
spec:
  rules:
  - http:
      paths:
      {{- range .Values.ingress}}
      - pathType: {{ .pathPrefix }}
        backend:
          service:
             name: {{ include "helm-app.name" . }}
             port: 
              number: {{ .Values.ingress.port }}
        path: {{ .Values.ingress.path }}
      {{- end}}
实现方案

完全可行,核心思路是在Terraform中动态生成Ingress规则配置,并将其传递给Ingress的Helm Chart(或单独的Ingress Helm资源)。具体操作如下:

1. 过滤并生成Ingress规则列表

定义Terraform本地变量,从var.releases_map中筛选需要配置Ingress的应用(ingress_configured = true),整理成Ingress模板所需的结构:

locals {
  ingress_rules = [
    for release_name, release_config in var.releases_map :
    {
      service_name  = release_name # 若服务名与Release名称不一致,可从helm_release的输出属性中获取
      service_port  = tonumber(release_config.service_port)
      path_prefix   = release_config.path_prefix
    }
    if release_config.ingress_configured
  ]
}

2. 将动态规则注入Ingress Helm资源

根据你的部署方式选择以下两种方案:

方案A:单独部署Ingress Helm Chart

如果使用独立的Ingress-Nginx Chart,在对应的helm_release资源中传递生成的规则:

resource "helm_release" "nginx_ingress" {
  name       = "nginx-ingress"
  chart      = "ingress-nginx/ingress-nginx"
  namespace  = "kube-system"
  repository = "https://kubernetes.github.io/ingress-nginx"

  set {
    name  = "controller.service.type"
    value = "LoadBalancer"
  }

  # 将动态规则注入Chart的values
  values = [
    yamlencode({
      ingress = {
        rules = local.ingress_rules
      }
    })
  ]
}

方案B:复用应用Chart的Ingress模板

若Ingress模板属于应用自身的Chart,调整模板为条件生成,并在应用的helm_release资源中传递规则:

resource "helm_release" "helm_releases" {
  for_each         = var.releases_map
  name             = each.key
  chart            = each.value.chart_source
  namespace        = each.value.namespace
  create_namespace = each.value.create_namespace

  values = [
    file("./helm-app/values.yaml"),
    yamlencode({
      ingress = {
        enabled = each.value.ingress_configured
        rules   = [
          {
            service_name  = each.key
            service_port  = tonumber(each.value.service_port)
            path_prefix   = each.value.path_prefix
          }
        ]
      }
    })
  ]

  set {
    name  = "deployment.replicaCount"
    value = each.value.replica_count
  }
  # 其他set配置...
}

3. 修正Ingress模板语法错误

原始模板存在变量引用和参数错误,修正后如下:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
spec:
  rules:
  - http:
      paths:
      {{- range .Values.ingress.rules}}
      - pathType: Prefix
        backend:
          service:
             name: {{ .service_name }}
             port: 
              number: {{ .service_port }}
        path: {{ .path_prefix }}
      {{- end}}

4. 新增应用的操作方式

后续新增应用时,只需在var.releases_map中添加条目,设置ingress_configured = true并指定path_prefix,执行terraform apply后,Terraform会自动将新应用的服务信息注入到Ingress规则中,无需手动修改Ingress配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 13:53:21