Rujhaan Bhatia
Rujhaan Bhatia

Reputation: 33

GCP ssh: handshake failed: ssh: unable to authenticate, attempted │ methods [none publickey], no supported methods remain

I'm learning terraform and want to create a new server and execute the shell script inside it using terraform provisioner. I'm facing this issue when terraform is trying to connect via SSH into newly created server.

I've gone through other solutions and verified that key is present at the correct location with 600 permission and also user is set by OS login but still getting same error

This is my main.tf file

provider "google" {
  project = var.project
  region  = var.region
}

resource "google_compute_firewall" "firewall" {
  name    = "gritfy-firewall-externalssh"
  network = "default"

  allow {
    protocol = "tcp"
    ports    = ["22","443"]
  }

  source_ranges = ["0.0.0.0/0"] # Not So Secure. Limit the Source Range
  target_tags   = ["externalssh"]
}

resource "google_compute_network" "default" {
  name = "test-network"
}



# We create a public IP address for our google compute instance to utilize
resource "google_compute_address" "static" {
  name       = "vm-public-address"
  project    = var.project
  region     = var.region
  depends_on = [google_compute_firewall.firewall]
}


resource "google_compute_instance" "dev" {
  name         = "devserver"
  machine_type = "e2-micro"
  zone         = "${var.region}-a"
  tags         = ["externalssh", "webserver"]

  boot_disk {
    initialize_params {
      image = "centos-cloud/centos-7"
    }
  }

  network_interface {
    network = "default"

    access_config {
      nat_ip = google_compute_address.static.address
    }
  }

  provisioner "file" {

    # source file name on the local machine where you execute terraform plan and apply
    source = "LAMP_Stack.sh"

    # destination is the file location on the newly created instance
    destination = "/tmp/LAMP_Stack.sh"

    connection {
      host = google_compute_address.static.address
      type = "ssh"
      user    = var.user
      timeout = "500s"
      private_key = file(var.privatekeypath)
    }
  }

  # to connect to the instance after the creation and execute few commands for provisioning
  provisioner "remote-exec" {
    connection {
      host = google_compute_address.static.address
      type = "ssh"
      # username of the instance would vary for each account refer the OS Login in GCP documentation
      user    = var.user
      timeout = "500s"
      # private_key being used to connect to the VM. ( the public key was copied earlier using metadata )
      private_key = file(var.privatekeypath)
    }

    # Commands to be executed as the instance gets ready.
    # set execution permission and start the script
    inline = [
      "chmod a+x /tmp/LAMP_Stack.sh",
      "sudo /tmp/LAMP_Stack.sh"
    ]
  }

  # Ensure firewall rule is provisioned before server, so that SSH doesn't fail.
  depends_on = [google_compute_firewall.firewall]

  service_account {
    email  = var.email
    scopes = ["compute-ro"]
  }
}

Upvotes: 0

Views: 710

Answers (1)

John Hanley
John Hanley

Reputation: 81356

When you created the Compute Engine instance, you did not specify metadata for the SSH RSA public key that matches the RSA private key that you are using.

Modify the username and id_rsa.pub filename.

variable "gce_ssh_user" {
  default = "username"
}

variable "gce_ssh_pub_key_file" {
  default = "id_rsa.pub"
}

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

The public key should have this format:

ssh-rsa AAAAB3NzaC1yc ... 0a9Wpd

An example command to create the SSH RSA private and public keys (id_rsa, id_rsa.pub):

ssh-keygen -t rsa -C "replace with username@hostname" -f id_rsa

Upvotes: 1

Related Questions