在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}")
}
}
}
答案 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"]
}