Terraform 将函数templatefile(path,vars)与远程执行资源调配器一起使用

Terraform 将函数templatefile(path,vars)与远程执行资源调配器一起使用,terraform,Terraform,对于terraform 0.12,有一个templatefile函数,但我还没有弄清楚如何将一个非平凡映射作为第二个参数传递给它,并将远程执行的结果作为新创建实例的配置步骤 这里是我试图做的要点,尽管它不能正确解析,因为不能在名为scriptstr的资源块中创建局部变量 当我真正尝试在远程端执行templatefile调用的输出时,一旦provisioner可以ssh到机器上,我已经尝试通过本地exec provisioner将templatefile调用输出写入本地文件。可能很简单,我只是没有

对于terraform 0.12,有一个templatefile函数,但我还没有弄清楚如何将一个非平凡映射作为第二个参数传递给它,并将远程执行的结果作为新创建实例的配置步骤

这里是我试图做的要点,尽管它不能正确解析,因为不能在名为scriptstr的资源块中创建局部变量

当我真正尝试在远程端执行templatefile调用的输出时,一旦provisioner可以ssh到机器上,我已经尝试通过本地exec provisioner将templatefile调用输出写入本地文件。可能很简单,我只是没有找到理解必要语法的文档或示例。短暂性脑缺血发作

resource "aws_instance" "server" {
  count = "${var.servers}"

  ami           = "${local.ami}"
  instance_type = "${var.instance_type}"
  key_name      = "${local.key_name}"

  subnet_id              = "${element(aws_subnet.consul.*.id, count.index)}"
  iam_instance_profile   = "${aws_iam_instance_profile.consul-join.name}"
  vpc_security_group_ids = ["${aws_security_group.consul.id}"]

  ebs_block_device {
    device_name = "/dev/sda1"
    volume_size = 2
  }

  tags = "${map(
    "Name", "${var.namespace}-server-${count.index}",
    var.consul_join_tag_key, var.consul_join_tag_value
  )}"

  scriptstr = templatefile("${path.module}/templates/consul.sh.tpl",
      {
        consul_version = "${local.consul_version}"

        config = <<EOF
         "bootstrap_expect": ${var.servers},
         "node_name": "${var.namespace}-server-${count.index}",
         "retry_join": ["provider=aws tag_key=${var.consul_join_tag_key} tag_value=${var.consul_join_tag_value}"],
         "server": true
        EOF
      })

  provisioner "local-exec" {
    command = "echo ${scriptstr} > ${var.namespace}-server-${count.index}.init.sh"
  }

  provisioner "remote-exec" {
    script = "${var.namespace}-server-${count.index}.init.sh"

    connection {
      type     = "ssh"
      user     = "clear"
      private_key = file("${local.private_key_file}")
    }
  }
}
资源“aws\u实例”“服务器”{
count=“${var.servers}”
ami=“${local.ami}”
instance_type=“${var.instance_type}”
key\u name=“${local.key\u name}”
subnet_id=“${element(aws_subnet.concur.*.id,count.index)}”
iam_instance_profile=“${aws_iam_instance_profile.consor join.name}”
vpc_security_group_id=[“${aws_security_group.consur.id}”]
ebs_块_设备{
设备名称=“/dev/sda1”
体积大小=2
}
tags=“${map(
“Name”、“${var.namespace}-server-${count.index}”,
var.consu\u join\u tag\u键,var.consu\u join\u tag\u值
)}"
scriptstr=templatefile(“${path.module}/templates/concur.sh.tpl”,
{
领事版本=“${local.consul\u version}”

config=在您的问题中,我可以看到您在这里试图解决的更高级别的问题是创建一个HashiCorp Consor服务器池,然后在它们全部启动后,告诉它们彼此的情况,以便它们可以组成一个集群

供应者基本上是“最后的手段”在Terraform中,出于实用性而提供的,因为有时登录主机并在主机上运行命令是完成任务的唯一方法。在这种情况下,可用的另一种方法是通过
aws\u实例
用户\u数据
参数将信息从Terraform传递到服务器,然后允许服务器立即启动并形成集群,而不是延迟到Terraform能够通过SSH进行连接

无论哪种方式,我通常都希望将我要运行的脚本的主体包含在AMI中,这样Terraform就可以使用一些参数来运行它,因为这样可以将问题简化为只对该脚本的调用进行模板化,而不是整个脚本:

  provisioner "remote-exec" {
    inline = ["/usr/local/bin/init-consul --expect='${var.servers}' etc, etc"]

    connection {
      type     = "ssh"
      user     = "clear"
      private_key = file("${local.private_key_file}")
    }
  }
但是,如果模板化整个脚本是您想要或需要做的,我会首先使用
文件
provisioner上传它,然后运行它,如下所示:

  provisioner "file" {
    destination = "/tmp/consul.sh"
    content = templatefile("${path.module}/templates/consul.sh.tpl", {
        consul_version = "${local.consul_version}"

        config = <<EOF
         "bootstrap_expect": ${var.servers},
         "node_name": "${var.namespace}-server-${count.index}",
         "retry_join": ["provider=aws tag_key=${var.consul_join_tag_key} tag_value=${var.consul_join_tag_value}"],
         "server": true
        EOF
    })
  }

  provisioner "remote-exec" {
    inline = ["sh /tmp/consul.sh"]
  }
provisioner“文件”{
destination=“/tmp/consul.sh”
content=templatefile(“${path.module}/templates/concur.sh.tpl”{
领事版本=“${local.consul\u version}”

config=你为什么要在那里而不是在本地这样做?我也不知道它是否会像在本地那样工作,但我不知道你为什么要尝试当前的方法。我想我不知道如何在资源中创建本地。全局本地将无法访问资源的count.index。谢谢你提供的详细信息。我已经离开美国了er_data angle,因为它不起作用,但其他东西也坏了。现在已经设置好了,可以使用文件和资源调配步骤(但不像您的解决方案那样干净),我回到了用户_数据方法,仍然发现aws实例没有创建脚本。aws控制台正确地显示了用户_数据。我在/var/lib/cloud/aws用户数据文件的第二部分看到了它。但是没有创建/var/lib/cloud/instances目录,也没有/usr/log/cloud-init-output.log。可能是clearlinux ami ...