如何使用 Terraform local-exec 在实例列表中组合 "IP" 和 "name"

How to combine "IP" and "name" in a list of instances with Terraform local-exec

我正在尝试从 Terraform 中读取实例 public_IP 和 instance_name,然后将它们写入同一行的文件中。

下一个命令,我写下一个文件:

provisioner "local-exec" {
  command =  "echo \"${join("\n", aws_instance.nodeStream.*.public_ip)}\" >> ../ouput_file"
}

output_file:

34.14.219.13
64.2.201.14
59.12.31.15

我想要的是下一个output_file:

34.14.219.13 instance_name1
64.2.201.14 instance_name2
59.12.31.15 instance_name3

所以我尝试了下一步来连接两个列表:

provisioner "local-exec" {
      command =  "echo \"${concat(sort(lookup(aws_instance.node1Stream.*.tags, "Name")), sort(aws_instance.node1Stream.*.public_ip))}\" >> ../../output_file"
    }

之前的投掷:

Error: Invalid function argument: Invalid value for "inputMap" parameter: lookup() requires a map as the first argument.

由于您的目标是从数据结构中生成字符串,这似乎是 string templates:

的一个很好的用途
locals {
  hosts_file_content = <<EOT
    %{ for inst in aws_instance.node1Stream ~}
    ${inst.private_ip} ${inst.tags["Name"]}
    %{ endfor ~}
  EOT
}

定义了本地值后,您可以将其包含在供应商的 command 参数中,如下所示:

  provisioner "local-exec" {
    command =  "echo '${local.hosts_file_content}' >> ../../output_file"
  }

如果您的最终目标只是将该数据放入文件中,而这不仅仅是为了这个问题而设计的示例,我建议您改用 local_file 资源,以便 Terraform可以像管理任何其他资源一样管理该文件,包括在输入更改时可能更新它而不需要任何特殊的配置器触发:

resource "local_file" "hosts_file" {
  filename = "${path.root}/../../output_file"
  content  = <<EOT
    %{ for inst in aws_instance.node1Stream ~}
    ${inst.private_ip} ${inst.tags["Name"]}
    %{ endfor ~}
  EOT
}

话虽如此,local_file 文档页面上的警告既适用于这种基于资源的方法,也适用于基于供应商的方法:Terraform 主要设计用于管理可以从一个 Terraform 持续存在的远程对象 运行 下一个,不适用于仅存在于 Terraform 当前 运行 的系统上的对象。尽管这些功能确实允许创建和修改本地文件,但您需要确保在下次应用更改时之前的文件在相对于 Terraform 配置的相同位置始终可用,否则 Terraform 将看到文件消失并被迫重新创建它。