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

时间:2019-08-14 13:39:38

标签: terraform

在terraform 0.12中,有一个templatefile函数,但我还没有弄清楚将非平凡的映射作为第二个参数传递给它,以及将结果作为新创建的实例的设置步骤远程执行的语法。 / p>

这是我要执行的操作的要点,尽管它不能正确解析,因为不能仅仅在名为scriptstr的资源块中创建局部变量。

虽然我实际上是想让模板文件调用的输出在远程执行,但是一旦供应者可以ssh到机器,我到目前为止已经走了尝试获取模板文件调用的道路。通过local-exec提供程序将输出写入本地文件。可能很容易,我只是没有找到文档或示例来了解必要的语法。 TIA

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}")
    }
  }
}

1 个答案:

答案 0 :(得分:1)

在您的问题中,我可以看到您似乎要在此处解决的更高级别的问题是创建一个HashiCorp Consul服务器池,然后在它们全部启动后互相告知彼此,以便它们可以形成集群。

本质上讲,供应商是Terraform中的“最后手段”,出于实用主义的考虑,因为有时登录到主机并在其上运行命令是完成工作的唯一方法。这种情况下可用的替代方法是通过aws_instance user_data参数将信息从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}")
    }
  }

但是,如果要对模板进行模板制作是您想要的或需要做的,我首先要使用file预配器将其上传,然后运行它,如下所示:

  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"]
  }