19

I am trying to connect VSCode to my GCP instances but am unable to. From a terminal, I can ssh into the machines with gcloud compute ssh my_machine_name but I'm not sure how to translate that into what VSCode Remote-SSH is looking for. When I created the config in VSCode I did this:

Host my_machine_name
    HostName my_machine_name
    User me@my_company.com

But the HostName is wrong because it's just the name of the machine and not the full HostName or IP address. I haven't even told VSCode that it's a GCP instance. How do I find the HostName? I imagine there's a connection between my_machine_name and the true HostName somewhere in my configs, but I can't find it. I found a GCP-Service.json file with the following keys:

{
  "type": 
  "project_id": 
  "private_key_id": 
  "private_key": 
  "client_email": 
  "client_id": 
  "auth_uri": 
  "token_uri": 
  "auth_provider_x509_cert_url": 
  "client_x509_cert_url": 
}

but I don't see anything that looks like a HostName or IP address.

Just to see, I tried to connect and got the following error:

Could not establish connection to "my_machine_name": Permission denied (publickey).

(Note sure if this is relevant but sometimes when I first try to connect I get the following, but after I click "Retry" it goes back to the publickey message again):

"Could not establish connection to "my_machine_name": Remote host key has changed, port forwarding is disabled."

So I tried to add a private key like so:

Host my_machine
    HostName my_machine
    User user@my_company.com
    IdentityFile ~/.ssh/id_rsa

I also tried the private key from my GCP-Service.json file as well but got the same result. What am I supposed to do to connect VSCode to my GCP instance?

jss367
  • 4,759
  • 14
  • 54
  • 76
  • Have a look at the following. I wrote it when using Cloud Shell but the same principles apply. If you're unable to get it to work, I'll have a look tomorrow: https://pretired.dazwilkin.com/posts/200917/ – DazWilkin Oct 16 '20 at 00:07
  • Ensure OSLoging is disabled. See Voy answer: https://serverfault.com/questions/641453/unable-to-ssh-to-gce-permission-denied-publickey/1014949#1014949 – Samuel Segal May 27 '21 at 18:27

4 Answers4

46

Simply running gcloud compute config-ssh, and you would get example-instance.us-central1-a.MY-PROJECT in your vs code ssh targets. Details at config-ssh

Panfeng Li
  • 3,321
  • 3
  • 26
  • 34
  • 7
    This is IMHO the better answer – rafee Jul 26 '21 at 05:28
  • 1
    Sorry complete noob here - can you explain step by step – Tariq Sep 12 '21 at 17:42
  • 2
    @Tariq read this https://learn.canceridc.dev/cookbook/virtual-machines/using-vs-code-with-gcp-vms – Innat Apr 09 '22 at 16:38
  • this is awesome, you can check and run `gcloud compute config-ssh` --project and simply `cat ~/.ssh/config` to see all your configs listed, it might be relevant to actually cat this into another file and define it and then inherit than overwhelm your config file – StanleyZheng May 31 '22 at 14:22
  • Wonderful answer. Someone should made a video on it – LonelySoul Jun 02 '22 at 04:27
  • That would be a perfect answer if your instances have public IP; otherwise it does not do anything with `WARNING: No host aliases were added to your SSH configs because instances have no public IP.` @Martin's Wang response down below is then the solution. – Jarek Jul 11 '22 at 07:15
8

Per my comment, this is straightforward and worked for me.

Assuming:

PROJECT=[[YOUR-PROJECT]]
INSTANCE=[[YOUR-INSTANCE]]
ZONE=[[YOUR-ZONE]]

This is slightly hacky but either:

USER=$(\
  gcloud compute ssh ${INSTANCE} \
  --zone=${ZONE} \
  --project=${PROJECT} \
  --command "whoami") && echo ${USER}

Or:

gcloud auth list --format="value(account)"
[[USER]]@[[DOMAIN]]

And:

IP=$(\
  gcloud compute instances describe ${INSTANCE} \
  --zone=${ZONE} \
  --project=${PROJECT} \
  --format='value(networkInterfaces[0].accessConfigs[0].natIP)') && echo ${IP}

NOTE the above assumes a single network interface and a public IP

Then, replacing the values with the above:

Host compute_engine
    HostName [[IP]]
    IdentityFile ~/.ssh/google_compute_engine
    User [[USER]]
    Port 22
DazWilkin
  • 32,823
  • 5
  • 47
  • 88
  • I tried this approach although I must have misunderstood a step because I wasn't able to get it to work. I edited my question with what I tried. – jss367 Oct 16 '20 at 20:54
  • 2
    You need to replace `IP` and `USER` with the actual values for your account and VM using the commands I showed – DazWilkin Oct 16 '20 at 21:13
  • For me it was actually `gcloud compute instances describe "$INSTANCE" --zone "$ZONE" --project "$PROJECT" --format='value(networkInterfaces.networkIP)'` – Ko Ga Jan 19 '23 at 14:47
6

It is also possible to use gcloud beta compute start-iap-tunnel INSTANCE_NAME 22 --listen-on-stdin to tunnel ssh access. (even without public ip)

gcloud iap tunnel docs

Your ssh config file:

Host YOUR_SERVER_NAME
    IdentityFile ~/.ssh/google_compute_engine
    User YOUR_USERNAME
    HostName YOUR_INSTANCE_NAME
    ProxyCommand gcloud beta compute start-iap-tunnel %h 22 --listen-on-stdin

Note: If you are running vscode client on windows, you may need to have something like this

ProxyCommand powershell -Command "gcloud beta compute start-iap-tunnel %h 22 --listen-on-stdin"

You can always test your ssh connection with ssh YOUR_SERVER_NAME -vvv, (and see if ProxyCommand works or not).


I have this in https://github.com/martinwang2002/gcp-vscode-server with start on ssh connection and stop if inactive feature.

Martin Wang
  • 61
  • 1
  • 1
1

If you already init gcloud successfully then you just need to type

gcloud compute config-ssh

Now you can access it with ssh HOSTNAME & it is also visible on your remote ssh vs code plugin. From your vs code, you can assess with ctrl+shift+p & connect to host and choose the host where you want to connect

Abdullah Al Mamun
  • 310
  • 2
  • 4
  • 14