如何遍历terraform中的所有aws_instances?

sko*_*hrs 3 amazon-ec2 terraform

我对terraform相对较新,并且正在尝试遍历所有aws_instances以应用null_resource。您可以使用多个splat来访问所有实例,而无论其名称如何?

EC2实例分为三种类型:

aws_instance.web.* (3 instances)
aws_instance.app.* (3 instances)
aws_instance.db.*  (2 instances)
Run Code Online (Sandbox Code Playgroud)

这是我尝试将null_resource应用于所有八个aws_instances的尝试:

resource "null_resource" "install_security_package" {

  #count = "${length(aws_instance)}" #terraform error: resource count can't reference variable: aws_instance
  #count = "${length(aws_instance.*)}" #terraform error: resource variables must be three parts: TYPE.NAME.ATTR
  count = "${length(aws_instance.*.*)}" #terraform error: unknown resource 'aws_instance.*'

  connection {
    type        = "ssh"
    host        = "${element(aws_instance.*.private_ip, count.index)}"
    user        = "${lookup(var.user, var.platform)}"
    private_key = "${file("${var.private_key_path}")}"
    timeout     = "2m"
  }

  provisioner "remote-exec" {
    inline = [
      "sudo rpm -Uvh http://www.example.com/security/repo/security_baseline.rpm",
    ]
  }
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*ins 6

当前不可能匹配给定类型的所有资源。如您所见,“ splat”语法仅允许选择从特定资源块创建的所有实例。

今天,使用Terraform最接近此功能的是将不同的资源连接在一起:

concat(aws_instance.web.*.private_ip, aws_instance.app.*.private_ip, aws_instance.db.*.private_ip)
Run Code Online (Sandbox Code Playgroud)

在此问题的当前版本的Terraform中,有必要使用github问题#4084中共享的一些解决方法,以避免在多个位置重复该复杂表达式。即将推出的称为“ 本地值”的功能将在不久的将来使此操作变得更简单,从而为该列表赋予一个名称,以便在多个地方重复使用:

# Won't work until Terraform PR#15449 is merged and released
locals {
  aws_instance_addrs = "${concat(aws_instance.web.*.private_ip, aws_instance.app.*.private_ip, aws_instance.db.*.private_ip)}"
}

resource "null_resource" "install_security_package" {

  count = "${length(local.aws_instance_addrs)}"

  connection {
    type        = "ssh"
    host        = "${local.aws_instance_addrs[count.index]}"
    user        = "${lookup(var.user, var.platform)}"
    private_key = "${file("${var.private_key_path}")}"
    timeout     = "2m"
  }

  provisioner "remote-exec" {
    inline = [
      "sudo rpm -Uvh http://www.example.com/security/repo/security_baseline.rpm",
    ]
  }
}
Run Code Online (Sandbox Code Playgroud)