首页 > 解决方案 > Template.tf 和 user_data.yaml.tpl- 通过 list 类型的变量循环

问题描述

我是模板的新手,我正在尝试将 terraform 模块更改为根据需要灵活地调整许多“名称服务器”。如何遍历变量的值?现在我正在做-

模板.tf -

variable "nameserver" {
  type = list(string)
}

nameservers = [
  "174.15.22.20",
  "174.15.12.21"
]

nameserver_1 = element(var.nameservers, 0) #nameserver_1=174.15.22.20
nameserver_2 = element(var.nameservers, 1) #nameserver_2=174.15.12.21

user_data.yaml.tpl

nameserver ${nameserver_1}
nameserver ${nameserver_2}

我想做一些类似的事情-

模板.tf

vars = {
   count = length(var.nameserver)
   for nameserver in nameservers:
   nameserver_$(count.index)= ${element(var.nameserver, 
  count.index)}
}

user_data.yaml.tpl

for nameserver in nameservers:
  nameserver  ${nameserver_[count.index]}

但无法在 template.tf 和 user_data.yaml.tpl 中找出正确的方法

任何帮助,将不胜感激 !

标签: terraform

解决方案


从您所展示的内容来看,template.tf我猜该vars = { ... }声明在一个data "template_file"块内。数据源主要是为了template_file与 Terraform 0.11 兼容,它只支持模板变量的字符串值,但由于您使用的是 Terraform 0.12,您可以改用新templatefile函数,通过支持任何类型的值,这使得这更容易。

根据您使用的模板名称,我猜您打算使用此结果分配给user_data,在这种情况下,执行此操作的语法templatefile如下所示:

  user_data = templatefile("${path.module}/user_data.yaml.tpl", {
    nameservers = var.nameservers
  })

在您的user_data.yaml.tpl文件中:

%{ for s in nameservers ~}
nameserver ${s}
%{ endfor ~}

这里的%{ ... }序列是Terraform 模板语法。相同的语法也可以直接在主配置文件中使用,因此对于这么小的模板,您可能更愿意只编写模板内联以使事情更简单:

  user_data = <<-EOT
    %{ for s in var.nameservers ~}
    nameserver ${s}
    %{ endfor ~}
  EOT

这里的模板语法是一样的,但是因为这是在主.tf配置文件中而不是在单独的模板文件中,所以我们可以直接在var.nameservers这里引用,而不是构建单独的模板变量映射。


您为模板文件提供的名称似乎表明您正在生成 YAML,尽管您显示的模板实际上并未生成有效的 YAML。如果您打算将结果设为 YAML,则 Terraform 中还有一些其他选项可能会更好,具体取决于您的目标:

首先,JSON 是 YAML 的一个子集,因此您可以让 Terraform 改为对您的数据进行 JSON 编码,然后您的实例中的 YAML 解析器(如果它符合 YAML 规范)应该能够解析它:

  user_data = jsonencode({
    nameservers = var.nameservers
  })

这种方法的一个优点是您可以让 Terraform 的jsonencode函数担心 JSON 语法、转义等,并且您可以将要表示的数据结构传递给它。如果它们可能包含重要的标点符号,则使用模板可能需要您处理值的引用或转义。

Terraform 的最新版本也有一个yamlencode功能,但在撰写本文时它是实验性的,它如何格式化其输出的确切细节可能会在未来的版本中发生变化。我不建议user_data现在使用它,因为如果语法细节在未来版本中确实发生了变化,那么这将导致您的实例被计划替换。在未来版本的 Terraform 中,一旦团队从实际使用中获得足够的反馈,确信其 YAML 格式化决策对于广泛的用例集是可以接受的,那么输出应该是稳定的。


推荐阅读