我是模板的新手,我试图更改terraform模块以根据需要伸缩任意多个“名称服务器”。如何遍历变量的值?现在我在做
template.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}
我想做类似的事情-
template.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中找出正确的方法
任何帮助将不胜感激!
答案 0 :(得分:0)
根据您对template.tf
的显示,我猜测vars = { ... }
声明位于data "template_file"
块内。 template_file
数据源主要是为了与Terraform 0.11兼容而存在的,并且仅支持模板变量的字符串值,但是由于您使用的是Terraform 0.12,因此可以使用新的templatefile
函数,这使此操作更容易通过支持任何类型的值。
从您使用的模板名称中,我猜测您打算将此结果分配给user_data
,在这种情况下,在templatefile
中执行此操作的语法如下所示:< / p>
user_data = templatefile("${path.module}/user_data.yaml.tpl", {
nameservers = var.nameservers
})
在您的user_data.yaml.tpl
文件中:
%{ for s in nameservers ~}
nameserver ${s}
%{ endfor ~}
此处的%{ ... }
序列为Terraform template syntax。相同的语法也可以直接在主配置文件中使用,因此对于这么小的模板,您可能更喜欢直接内联编写模板以简化操作:
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
,因为如果语法详细信息 do 在将来的版本中发生更改,则将导致您的实例计划进行替换。在将来的Terraform版本中,一旦团队从实际使用中获得足够的反馈,就可以稳定输出,从而可以确信其YAML格式决定对于一系列用例都是可以接受的。