'How to add an ssh key to an GCP instance using terraform?

So I have a terraform script that creates instances in Google Cloud Platform, I want to be able to have my terraform script also add my ssh key to the instances I create so that I can provision them through ssh. Here is my current terraform script.

#PROVIDER INFO
provider "google" {
  credentials = "${file("account.json")}"
  project     = "myProject"
  region      = "us-central1"
}


#MAKING CONSUL SERVERS
resource "google_compute_instance" "default" {
  count    =  3
  name     =  "a-consul${count.index}"
  machine_type = "n1-standard-1"
  zone         = "us-central1-a"

  disk {
    image = "ubuntu-1404-trusty-v20160627"
  }

  # Local SSD disk
  disk {
    type    = "local-ssd"
    scratch = true
  }

  network_interface {
    network = "myNetwork"
    access_config {}
  }
}

What do I have to add to this to have my terraform script add my ssh key /Users/myUsername/.ssh/id_rsa.pub?



Solution 1:[1]

I think something like this should work:

  metadata = {
    ssh-keys = "${var.gce_ssh_user}:${file(var.gce_ssh_pub_key_file)}"
  }

https://cloud.google.com/compute/docs/instances/adding-removing-ssh-keys describes the metadata mechanism, and I found this example at https://github.com/hashicorp/terraform/issues/6678

Solution 2:[2]

Just for the record. As of 0.12 it seems the block should look like:

resource "google_compute_instance" "default" {
  # ...

  metadata = {
    ssh-keys = join("\n", [for user, key in var.ssh_keys : "${user}:${key}"])
  }

  # ...
}

(Note = sign after metadata token and ssh-keys vs. sshKeys).

Solution 3:[3]

Here is tested one.

  metadata {
    sshKeys = "${var.ssh_user}:${var.ssh_key} \n${var.ssh_user1}:${var.ssh_key1}"
}

Solution 4:[4]

If you want multiple keys you can use heredoc like this

  metadata = {
    "ssh-keys" = <<EOT
<user>:<key>
<user>:<key>
EOT
  }

I stayed with the weird formatting here in the post that terraform fmt provided me.

Solution 5:[5]

You can use the following

metadata = {
  ssh-keys = "username:${file("username.pub")}"
}

I was struggling to create an instance with the ssh key using terraform & this answer is tested & working as well.

Solution 6:[6]

Just updating for multiple keys in Terraform v0.15.4:

metadata = {
    ssh-keys = join("\n", [for key in var.ssh_keys : "${key.user}:${key.publickey}"])
}

And accoring variables:

variable "ssh_keys" {
  type = list(object({
    publickey = string
    user = string
  }))
  description = "list of public ssh keys that have access to the VM"
  default = [
      {
        user = "username"
        publickey = "ssh-rsa yourkeyabc username@PC"
      }
  ]
}

Solution 7:[7]

I have below working for me: for all vms a single ssh key

resource "google_compute_project_metadata" "my_ssh_key" {
  metadata = {
    ssh-keys = <<EOF
      terakey:ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICqaF7TqtimTUtqLdZIspKjuTXXXXnkbW7N9TQBPXazu terakey
      
    EOF
  }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Chris Stryczynski
Solution 2 0x416e746f6e
Solution 3 4b0
Solution 4 hashier
Solution 5 mariux
Solution 6
Solution 7 Arnie97