在 Terraform 0.12 中遍历地图的地图
Iterate Through Map of Maps in Terraform 0.12
我需要像这样构建 templatefile
的列表:
templatefile("${path.module}/assets/files_eth0.nmconnection.yaml", {
interface-name = "eth0",
addresses = element(values(var.virtual_machines), count.index),
gateway = element(var.gateway, count.index % length(var.gateway)),
dns = join(";", var.dns_servers),
dns-search = var.domain,
}),
templatefile("${path.module}/assets/files_etc_hostname.yaml", {
hostname = element(keys(var.virtual_machines), count.index),
}),
通过遍历地图的地图,如下所示:
variable templatefiles {
default = {
"files_eth0.nmconnection.yaml" = {
"interface-name" = "eth0",
"addresses" = "element(values(var.virtual_machines), count.index)",
"gateway" = "element(var.gateway, count.index % length(var.gateway))",
"dns" = "join(";", var.dns_servers)",
"dns-search" = "var.domain",
},
"files_etc_hostname.yaml" = {
"hostname" = "host1"
}
}
}
我对文件列表做了类似的事情:
file("${path.module}/assets/files_90-disable-console-logs.yaml"),
file("${path.module}/assets/files_90-disable-auto-updates.yaml"),
...但想将其扩展为 templatefiles
(以上)。
这是我为 files
的列表所做的代码:
main.tf
variable files {
default = [
"files_90-disable-auto-updates.yaml",
"files_90-disable-console-logs.yaml",
]
}
output "snippets" {
value = flatten(module.ingition_snippets.files)
}
modules/main.tf
variable files {}
resource "null_resource" "files" {
for_each = toset(var.files)
triggers = {
snippet = file("${path.module}/assets/${each.value}")
}
}
output "files" {
value = [for s in null_resource.files: s.triggers.*.snippet]
}
感谢任何帮助!
这两个用例都可以在根本不使用任何 resource
块的情况下得到满足,因为 Terraform 语言中内置了必要的功能。
下面是使用静态文件编写示例的更短方式:
variable "files" {
type = set(string)
}
output "files" {
value = tomap({
for fn in var.files : fn => file("${path.module}/assets/${fn}")
})
}
上面会生成一个从文件名到文件内容的映射,因此调用模块可以更轻松地访问各个文件内容。
我们可以像这样为 templatefile
调整它:
variable "template_files" {
# We can't write down a type constraint for this case
# because each file might have a different set of
# template variables, but our later code will expect
# this to be a mapping type, like the default value
# you shared in your comment, and will fail if not.
type = any
}
output "files" {
value = tomap({
for fn, vars in var.template_files : fn => templatefile("${path.module}/assets/${fn}", vars)
})
}
同样,结果将是从文件名到使用给定变量呈现模板的结果的映射。
如果您的目标是构建一个用于从源目录呈现模板以发布到某处的模块,您可能会发现模块 hashicorp/dir/template
很有用。它结合了 fileset
、file
和 templatefile
,希望能方便静态网站发布和类似用例。 (在我写这篇文章的时候,该模块正在从我的个人 GitHub 帐户过渡到 HashiCorp 组织,所以如果您在文档更新后不久查看它,您可能会看到一些动荡,等等。 )
我需要像这样构建 templatefile
的列表:
templatefile("${path.module}/assets/files_eth0.nmconnection.yaml", {
interface-name = "eth0",
addresses = element(values(var.virtual_machines), count.index),
gateway = element(var.gateway, count.index % length(var.gateway)),
dns = join(";", var.dns_servers),
dns-search = var.domain,
}),
templatefile("${path.module}/assets/files_etc_hostname.yaml", {
hostname = element(keys(var.virtual_machines), count.index),
}),
通过遍历地图的地图,如下所示:
variable templatefiles {
default = {
"files_eth0.nmconnection.yaml" = {
"interface-name" = "eth0",
"addresses" = "element(values(var.virtual_machines), count.index)",
"gateway" = "element(var.gateway, count.index % length(var.gateway))",
"dns" = "join(";", var.dns_servers)",
"dns-search" = "var.domain",
},
"files_etc_hostname.yaml" = {
"hostname" = "host1"
}
}
}
我对文件列表做了类似的事情:
file("${path.module}/assets/files_90-disable-console-logs.yaml"),
file("${path.module}/assets/files_90-disable-auto-updates.yaml"),
...但想将其扩展为 templatefiles
(以上)。
这是我为 files
的列表所做的代码:
main.tf
variable files {
default = [
"files_90-disable-auto-updates.yaml",
"files_90-disable-console-logs.yaml",
]
}
output "snippets" {
value = flatten(module.ingition_snippets.files)
}
modules/main.tf
variable files {}
resource "null_resource" "files" {
for_each = toset(var.files)
triggers = {
snippet = file("${path.module}/assets/${each.value}")
}
}
output "files" {
value = [for s in null_resource.files: s.triggers.*.snippet]
}
感谢任何帮助!
这两个用例都可以在根本不使用任何 resource
块的情况下得到满足,因为 Terraform 语言中内置了必要的功能。
下面是使用静态文件编写示例的更短方式:
variable "files" {
type = set(string)
}
output "files" {
value = tomap({
for fn in var.files : fn => file("${path.module}/assets/${fn}")
})
}
上面会生成一个从文件名到文件内容的映射,因此调用模块可以更轻松地访问各个文件内容。
我们可以像这样为 templatefile
调整它:
variable "template_files" {
# We can't write down a type constraint for this case
# because each file might have a different set of
# template variables, but our later code will expect
# this to be a mapping type, like the default value
# you shared in your comment, and will fail if not.
type = any
}
output "files" {
value = tomap({
for fn, vars in var.template_files : fn => templatefile("${path.module}/assets/${fn}", vars)
})
}
同样,结果将是从文件名到使用给定变量呈现模板的结果的映射。
如果您的目标是构建一个用于从源目录呈现模板以发布到某处的模块,您可能会发现模块 hashicorp/dir/template
很有用。它结合了 fileset
、file
和 templatefile
,希望能方便静态网站发布和类似用例。 (在我写这篇文章的时候,该模块正在从我的个人 GitHub 帐户过渡到 HashiCorp 组织,所以如果您在文档更新后不久查看它,您可能会看到一些动荡,等等。 )