使用Terraform,我需要将文件复制到Google Compute Engine实例模板。为此,我通常使用file provisioner,但它不起作用,因为它依赖于SSH connections,由于需要外部可访问的主机地址而失败。由于实例模板的动态特性,我不知道如何为实例分配外部可访问的主机地址。
如何实现将文件复制到通过实例模板创建的GCE实例(通过Terraform)?
resource "google_compute_instance_template" "node" {
name = "kubernetes-node-template"
machine_type = "g1-small"
can_ip_forward = true
tags = ["staging", "node"]
network_interface {
network = "default"
}
provisioner "file" {
source = "worker/assets/kubelet.service"
destination = "/etc/systemd/system/kubelet.service"
}
connection {
user = "core"
type = "ssh"
private_key = "${file("~/.ssh/id_rsa")}"
}
}
答案 0 :(得分:4)
我能够通过以下配置解决此问题。
resource "google_compute_instance" "hubmud" {
name = "hubmud"
machine_type = "f1-micro"
tags = ["buildserver", "jenkins", "central", "terraformer"]
tags = [ "http-server" ]
zone = "us-central1-b"
disk {
image = "ubuntu-1404-trusty-v20160406"
}
network_interface {
network = "default"
access_config {}
}
provisioner "file" {
source = "installations.sh"
destination = "installations.sh"
connection {
type = "ssh"
user = "ubuntu"
private_key = "${file("~/.ssh/google_compute_engine")}"
}
}
provisioner "remote-exec" {
inline = [
"chmod +x ~/installations.sh",
"cd ~",
"./installations.sh"
]
connection {
type = "ssh"
user = "ubuntu"
private_key = "${file("~/.ssh/google_compute_engine")}"
}
}
service_account {
scopes = ["userinfo-email", "compute-ro", "storage-ro"]
}
}
我使用的SSH密钥是由gcloud实例生成的密钥,要复制的文件必须采用如图所示的格式。我确实遇到了使用~/
或仅./
来指定文件位置的问题。注意在" ubuntu"下复制的文件也很重要。帐户,默认情况下,GCE在图像上显示为ubuntu上的默认帐户。
请注意,即使这是连接类型的默认设置,我也添加了type = "ssh"
,因此不需要。我喜欢在配置文件中添加一些详细信息,所以我添加了它。
答案 1 :(得分:0)
您可以SSH进入 google_compute_instance (毕竟这是一个具体的虚拟VM),但既不能进入 google_compute_instance_group_manager 也不能进入SSH google_compute_instance_template >因为这些是抽象。
如此处https://github.com/terraform-providers/terraform-provider-google/issues/52所述,目前尚无法实现。
答案 2 :(得分:0)
首次启动实例时,您可以将元数据用于运行脚本,并且可以执行任何操作,但只能运行一次。要进行重放,元数据需要重新创建实例。
metadata = {
startup-script = "echo LOL SSH CONNECTION > /test.info"
}
OR
metadata = {
startup-script = "${file("${path.module}/shared/runner/bootstrap.sh")}"
}
答案 3 :(得分:0)
也许此功能是稍后添加的,但从 2021 年初开始,您可以使用 metadata_startup_script 的可选 google_compute_instance_template 参数来指定每次从模板创建的任何实例启动时都会运行的脚本:
resource "google_compute_instance" "hubmud" {
name = "hubmud"
machine_type = "f1-micro"
tags = ["buildserver", "jenkins", "central", "terraformer"]
tags = [ "http-server" ]
zone = "us-central1-b"
disk {
image = "ubuntu-1404-trusty-v20160406"
}
network_interface {
network = "default"
access_config {}
}
# As per the documentation for google_compute_instance_template (https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/compute_instance_template#metadata_startup_script)
# you can set either metadata.startup-script or metadata_startup_script
# to the contents of a file that will be added to the metadata of
# any instance created from the template.
# In both cases the script will run each time the instance starts.
# The difference is that if metadata_startup_script is used and the metadata
# value is changed the instance will be destroyed and recreated before
# running the new script.
metadata_startup_script = file("${path.module}/installations.sh")
service_account {
scopes = ["userinfo-email", "compute-ro", "storage-ro"]
}
}
请注意,此机制需要操作系统支持,但正如 the documentation for the underlying arguments on google_compute_instance 指出的那样:
“大多数基于 linux 的映像将在每次启动时在 shell 中运行 metadata.startup-script 的内容。至少,Debian、CentOS、RHEL、SLES、Container-Optimized OS 和 Ubuntu 映像支持此密钥。 Windows 实例需要其他密钥,具体取决于脚本的格式和您希望它运行的时间。”
早在 Ubuntu 16.04 就进行了测试,它在本月底达到了 LTS 的 EOL。所以这个功能已经存在了 5 年以上。不清楚它是否在很久以前被 GCP Terraform 提供者公开,但现在它可以完美运行。