Terraform部署GCP实例SSH握手失败,认证问题求助
错误说明
你遇到的SSH认证错误:GCP ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain
结合你的配置和排查情况,以下是针对性的解决步骤:
1. 确认OS Login在实例上已启用
即使你全局配置了OS Login,GCP实例默认不会自动启用该功能,需要在实例资源中显式添加元数据开启:
resource "google_compute_instance" "dev" { # ...其他配置 metadata = { enable-oslogin = "TRUE" } }
同时,你需要确保用于连接的var.user是OS Login生成的用户名,而非本地系统用户名。可以通过以下命令查看你的OS Login用户名:
gcloud compute os-login describe-profile
输出中的posixAccounts[0].username字段就是你需要用的SSH用户名。
2. 验证公钥与OS Login的绑定
确保你的本地公钥已正确导入到GCP OS Login中:
gcloud compute os-login ssh-keys add --key-file=/path/to/your/public/key.pub
同时,确认该公钥关联的GCP账号拥有实例的访问权限(至少需要roles/compute.osLogin角色)。
3. 修正网络配置冲突
你的配置中创建了名为test-network的自定义网络,但防火墙和实例都使用了默认的default网络,这会导致自定义网络资源闲置,也可能引发潜在的网络规则问题。请统一网络配置:
- 修正防火墙的网络指向自定义网络:
resource "google_compute_firewall" "firewall" { name = "gritfy-firewall-externalssh" network = google_compute_network.default.name # 替换为自定义网络资源引用 # ...其他配置 } - 实例的网络接口也使用自定义网络:
network_interface { network = google_compute_network.default.name # ...其他配置 }
4. 优化SSH连接配置
在Terraform的connection块中添加以下配置,避免本地SSH代理干扰并简化认证流程:
connection { host = google_compute_address.static.address type = "ssh" user = var.os_login_user # 替换为OS Login用户名 timeout = "500s" private_key = file(var.privatekeypath) agent = false # 禁用SSH代理,强制使用指定私钥 }
5. 替代方案:直接注入SSH密钥到实例元数据
如果OS Login配置仍有问题,可以暂时绕过OS Login,直接将公钥注入到实例元数据中:
resource "google_compute_instance" "dev" { # ...其他配置 metadata = { ssh-keys = "${var.user}:${file(var.publickeypath)}" } }
注意这里的var.user需要是实例的默认用户名(CentOS 7默认是centos),公钥文件内容要完整且格式正确。
内容的提问来源于stack exchange,提问作者Rujhaan Bhatia

