在Terraform 0.12中遍历地图

时间:2020-04-28 01:04:34

标签: terraform nested-loops

我需要像这样建立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]
}

感谢任何帮助!

1 个答案:

答案 0 :(得分:1)

这两个用例完全可以满足,而无需使用任何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很有用。它将filesetfiletemplatefile组合在一起,希望可以为静态网站发布和类似用例提供方便。 (在我撰写本文时,该模块正在从我的个人GitHub帐户过渡为HashiCorp组织的身份,因此如果您很快查看它,可能会在文档更新后看到一些动荡,等等。)