highFoundationSymptom-first#compute engine#ssh#external ip#iam#connectivity

GCE VM has no external IP / SSH key not recognized

gcloud compute ssh <INSTANCE> times out or reports Connection refused

Likely source:configurationconnectivity

Focused incident mode — strips away everything but this runbook.

Symptoms

  • gcloud compute ssh <INSTANCE> times out or reports Connection refused
  • Instance has no External IP address in the console
  • SSH key authentication fails with Permission denied (publickey)
  • Fresh VM was created with a different service account or SSH keys

Internal-only VMs are common in security-hardened projects — reach them with IAP Tunneling (gcloud compute ssh --tunnel-through-iap) instead of adding public IPs.

Evidence to grab

Collect these artifacts before you change anything — they prove (or rule out) each cause.

  • Network interfaces and external IP

    gcloud compute instances describe <INSTANCE> --zone=<ZONE> --format='value(networkInterfaces)'
  • Project/instance metadata SSH keys

    gcloud compute instances describe <INSTANCE> --zone=<ZONE> --format='value(metadata.ssh-keys)'

Diagnostic flow

Run the steps in order, marking each claim confirmed or refuted. The evidence you gather feeds the ranked causes below.

Guided decision tree is ready.

Steps with commands, expected output, and pass/fail branches.

Ranked root causes

Evidence checklist

  • networkInterfaces accessConfigs is empty
  • Instance is behind only an internal VPC with no NAT or bastion

Confirm before fixing

gcloud compute instances describe <INSTANCE> --zone=<ZONE> --format='value(networkInterfaces[0].accessConfigs[0].natIP)'
READ

Check for an external NAT IP

Expected: Empty result

Fix

gcloud compute instances add-access-config <INSTANCE> --zone=<ZONE> --access-config-name=external-nat --nat-ip=<EPHEMERAL_IP>
CHANGE

Attach an ephemeral external IP to reach the VM directly

Expected: Adding access config to instance [<INSTANCE>]...

Resolution runbook

Apply from top to bottom after the cause is confirmed. Review every command before running it — risk tags are shown on each.

1
gcloud compute instances describe <INSTANCE> --zone=<ZONE> --format='value(networkInterfaces[0].accessConfigs[0].natIP)'
READ

Confirm an external IP exists

2
gcloud compute firewall-rules list --filter='allowed[].ports=22' --format='table(name,network,sourceRanges)'
READ

Make sure tcp:22 is allowed from your source range

3
gcloud compute ssh <INSTANCE> --zone=<ZONE> --troubleshoot
READ

Use Google's SSH diagnostics to find the blocker

4
gcloud compute ssh <INSTANCE> --zone=<ZONE> --command='echo reachable'
READ

Confirm end-to-end connectivity

Prevention

  • Enable OS Login so key management is IAM-driven instead of metadata-based.
  • Prefer IAP Tunneling or a managed proxy over direct external IPs for SSH.
  • Scaffold firewall rules for SSH as part of the network module.
  • Test gcloud compute ssh before first deploy to catch missing IP/key issues early.

Commands marked READ CHANGE DESTRUCTIVE — never run DESTRUCTIVE commands against production data you cannot restore. Copy → verify → execute.