Startup script on google instance terraform

google-cloud-platformterraform

I am trying do a startup script on my instance but nothing append, the env variables are not in the system when i loggin on a instance, any ideas ?

resource "google_compute_instance_template" "vault_template" {
  name_prefix = "vault-template-"

  machine_type = "n1-standard-2"
  region       = "${var.google_region}"

  scheduling {
    automatic_restart   = true
    on_host_maintenance = "MIGRATE"
  }

  disk {
    disk_type    = "pd-standard"
    source_image = "${var.google_image_name}"
    disk_size_gb = 100
  }
  lifecycle {
    create_before_destroy = true
  }
  network_interface {
    network = "default"
    access_config {
    }
  }
  service_account {
    email  = "${var.google_email}"
    scopes = ["storage-rw"]
  }
  metadata = {
    startup_script = <<SCRIPT
      export API_ADDR="http://$(curl -sf -H 'Metadata-Flavor:Google' http://metadata/computeMetadata/v1/instance/network-interfaces/0/ip | tr -d '\n'):8200"
      export CLUSTER_ADDR="https://$(curl -sf -H 'Metadata-Flavor:Google' http://metadata/computeMetadata/v1/instance/network-interfaces/0/ip | tr -d '\n'):8201"
      export VAULT_ADDR="http://127.0.0.1:8200"
      SCRIPT
  }

}

Best Answer

The export command in the bash shell defines a new environment variable only for the current shell session. The variables defined that way are lost as soon as that session of the shell exits.

To make that more concrete, it would work to make use of those variables immediately after you declare them in the same script:

export API_ADDR="http://$(curl -sf -H 'Metadata-Flavor:Google' http://metadata/computeMetadata/v1/instance/network-interfaces/0/ip | tr -d '\n'):8200"
export CLUSTER_ADDR="https://$(curl -sf -H 'Metadata-Flavor:Google' http://metadata/computeMetadata/v1/instance/network-interfaces/0/ip | tr -d '\n'):8201"
export VAULT_ADDR="http://127.0.0.1:8200"
echo >/tmp/example.txt "Vault is at ${VAULT_ADDR}"

...but these variables will not be visible to any other program started on the system, or in a shell created by logging in over SSH, because they exist only for the duration of the startup script.

If you goal is to have those variables be available when you log in to the system e.g. over SSH, you'll need to add them to one of the startup scripts your shell reads when starting a new session.

For example, if you are using the bash shell then you could write a startup script that appends more items to the .bash_profile file in your user's home directory:

API_ADDR="http://$(curl -sf -H 'Metadata-Flavor:Google' http://metadata/computeMetadata/v1/instance/network-interfaces/0/ip | tr -d '\n'):8200"
CLUSTER_ADDR="https://$(curl -sf -H 'Metadata-Flavor:Google' http://metadata/computeMetadata/v1/instance/network-interfaces/0/ip | tr -d '\n'):8201"
VAULT_ADDR="http://127.0.0.1:8200"

cat >>/home/username/.bash_profile <<EOT
# Added by instance startup script
export API_ADDR=\'"$API_ADDR"\'
export CLUSTER_ADDR=\'"$CLUSTER_ADDR"\'
export VAULT_ADDR=\'"$VAULT_ADDR"\'
EOT

The above assumes that your user's home directory is /home/username, so you'll need to adjust that to the correct location. This is a script that generates another script, so unfortunately it has some awkward escaping to ensure that the resulting script will be valid even if the variable values contain awkward characters that a shell might consider to be significant.

Note that the script generated above only applies to shells and programs started from shells. If you are running any software using systemd or some other supervisor program then these variables won't be visible to those; you'll need to generate configuration for the supervisor program to launch the programs with these variables as well.