如何将文件提供器与google_compute_instance_template一起使用



使用Terraform,我需要将文件复制到Google计算引擎实例模板中。为此,我通常使用文件设置器,但它不起作用,因为它依赖于SSH连接,而SSH连接由于需要外部可访问的主机地址而失败。由于实例模板的动态特性,我不知道如何将外部可访问的主机地址分配给实例。

如何将文件复制到通过实例模板创建的GCE实例(通过Terraform)?

Terraform google_compute_instance_template定义示例

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

我通过以下配置解决了这个问题。

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"帐户下复制的,该帐户似乎是ubuntu上的默认帐户,GCE默认情况下在图像上具有该帐户。

需要注意的是,我还添加了type = "ssh",尽管这是连接类型的默认值,所以不需要它。不过,我喜欢在配置文件中详细说明一些内容,所以我添加了它。

您可以将SSH连接到google_computer_instances(毕竟这是一个具体的、有形的虚拟机)中,但既不能连接到google_compute_instance_group_manager中,也不能连接到google_coumpute_instante_template,因为这些都是抽象的。

如此处所述https://github.com/terraform-providers/terraform-provider-google/issues/52,目前这是不可能的。

也许这个功能是后来添加的,但从2021年初开始,您可以使用google_compute_instance_template的可选metadata_startup_script参数来指定一个脚本,该脚本将在每次从模板创建的任何实例启动时运行:

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

注意,这种机制需要操作系统的支持,但正如google_computer_instance上底层参数的文档所指出的那样:

"大多数基于linux的映像在每次启动时都会在shell中运行metadata.startup-script的内容。Debian、CentOS、RHEL、SLES、Container Optimized OS和Ubuntu映像至少支持此密钥。Windows实例需要其他密钥,具体取决于脚本的格式和运行时间"

早在Ubuntu 16.04就进行了测试,它将于本月底达到LTS的EOL。所以这个功能已经存在了5年多了。尚不清楚GCP Terraform提供商是否早就公开了它,但现在它运行得很好。

当您第一次启动实例时,您可以为运行脚本和其他操作使用元数据,但它只能工作一次。对于重播,元数据需要重新创建实例。

metadata = {
    startup-script = "echo LOL SSH CONNECTION > /test.info"
}
OR
metadata = {
    startup-script = "${file("${path.module}/shared/runner/bootstrap.sh")}"
}

最新更新