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
相关产品推荐
相关产品推荐

