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

Terraform template_file资源遍历locals.k8_manifest端口配置咨询

问题修复方案

1. 首先修正locals定义错误

你原来的ports字段使用了重复key的map结构,Terraform中map的key不能重复,后面的端口会覆盖前面的,直接改为列表存储端口即可:

locals {
  k8_manifest = {
    "alertmanager" = {
      name                          = "alertmanager"
      namespace                     = "victoriametrics"
      label_k8s-app                 = "alertmanager"
      label_purpose                 = "victoriametrics"
      description                   = "Prometheus alert manager for send"
      replicas_number               = 1
      container_name                = "alertmanager"
      container_image_address       = "11111111111.dkr.ecr.us-east-1.amazonaws.com/alertmanager:0.23.0"
      restartPolicy                 = "Always"
      terminationGracePeriodSeconds = "30"
      dnsPolicy                     = "ClusterFirst"
      schedulerName                 = "default-scheduler"
      strategy_type_update          = "RollingUpdate"
      resources_cpu                 = "1"
      resources_memory              = "1Gi"
      # 改为列表存储端口,避免重复key问题
      ports = ["9093", "9094", "9096"]
    },
  }
}

2. 修正template_file配置

dynamic块只能用于Terraform资源/数据源的顶层参数,不能在vars字段中使用,直接把ports列表传入变量即可,另外注意template_file已经被官方废弃,更推荐使用内置templatefile函数,两种写法都提供:

写法1:沿用template_file(不推荐)

data "template_file" "k8_manifest" {
  for_each = local.k8_manifest
  template = file("${path.module}/manifests/manifests.tpl")

  vars = {
    name                          = try(each.value.name, null)
    namespace                     = try(each.value.namespace, null)
    label_k8s-app                 = try(each.value.label_k8s-app, null)
    label_purpose                 = try(each.value.label_purpose, null)
    description                   = try(each.value.description, null)
    replicas_number               = try(each.value.replicas_number, null)
    container_name                = try(each.value.container_name, null)
    container_image_address       = try(each.value.container_image_address, null)
    restartPolicy                 = try(each.value.restartPolicy, null)
    terminationGracePeriodSeconds = try(each.value.terminationGracePeriodSeconds, null)
    dnsPolicy                     = try(each.value.dnsPolicy, null)
    schedulerName                 = try(each.value.schedulerName, null)
    strategy_type_update          = try(each.value.strategy_type_update, null)
    resources_cpu                 = try(each.value.resources_cpu, null)
    resources_memory              = try(each.value.resources_memory, null)
    # 直接传ports列表即可
    ports = try(each.value.ports, [])
  }
}

写法2:使用官方推荐的templatefile函数(推荐)

直接在需要用到渲染后manifest的地方调用即可,不需要单独定义数据源:

# 示例:渲染后传给kubernetes_deployment资源,或者写入本地文件
locals {
  rendered_manifests = {
    for k, v in local.k8_manifest : k => templatefile("${path.module}/manifests/manifests.tpl", {
      name                          = try(v.name, null)
      namespace                     = try(v.namespace, null)
      label_k8s-app                 = try(v.label_k8s-app, null)
      label_purpose                 = try(v.label_purpose, null)
      description                   = try(v.description, null)
      replicas_number               = try(v.replicas_number, null)
      container_name                = try(v.container_name, null)
      container_image_address       = try(v.container_image_address, null)
      restartPolicy                 = try(v.restartPolicy, null)
      terminationGracePeriodSeconds = try(v.terminationGracePeriodSeconds, null)
      dnsPolicy                     = try(v.dnsPolicy, null)
      schedulerName                 = try(v.schedulerName, null)
      strategy_type_update          = try(v.strategy_type_update, null)
      resources_cpu                 = try(v.resources_cpu, null)
      resources_memory              = try(v.resources_memory, null)
      ports = try(v.ports, [])
    })
  }
}

3. 修正模板文件语法

你原来的模板循环语法用错了,Terraform模板的控制语句以%{开头,不是{%,且循环时要使用迭代变量,不能直接引用整个列表:

kind: Deployment
apiVersion: apps/v1
metadata:
  name: ${name}
  namespace: ${namespace}
  labels:
    k8s-app: ${label_k8s-app}
    purpose: ${label_purpose}
  annotations:
    description: ${description}
spec:
  replicas: ${replicas_number}
  selector:
    matchLabels:
      k8s-app: ${label_k8s-app}
      purpose: ${label_purpose}
  template:
    metadata:
      name: ${name}
      labels:
        k8s-app: ${label_k8s-app}
        purpose: ${label_purpose}
      annotations:
        description: ${description}
    spec:
      containers:
        - name: ${name}
          image: ${container_image_address}
          ports:
            %{ for port in ports ~}
            - containerPort: ${port}
            %{ endfor ~}
          resources:
            requests:
              cpu: ${resources_cpu}
              memory: ${resources_memory}
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      dnsPolicy: ClusterFirst
      schedulerName: default-scheduler
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25%
  revisionHistoryLimit: 10
  progressDeadlineSeconds: 300

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 05:54:02