Terraform创建AWS EC2实例遇SSH握手失败及密钥使用问题求助
问题回顾
你在使用Terraform创建两台EC2实例时,配置了remote-exec provisioner来修改主机名,但一直遭遇SSH握手失败的超时循环错误,具体报错如下:
- aws_instance.ins2_ec2: timeout - last error: ssh: handshake failed: agent: failed to list keys
- aws_instance.ins1_ec2: timeout - last error: ssh: handshake failed: agent: failed to list keys
你的Terraform代码里既没给EC2实例关联密钥对,也没给remote-exec指定SSH连接的密钥信息,这就是问题的核心所在。
核心错误原因
Terraform的remote-exec provisioner需要通过SSH连接到EC2实例执行命令,但当前配置存在两个关键缺失:
- EC2实例未关联AWS密钥对,导致实例本身不允许密钥登录
remote-exec没有明确指定私钥路径,Terraform无法自动获取可用的身份验证密钥
解决方案:添加密钥对配置与SSH连接信息
1. 确认AWS密钥对状态
首先要确保你的test.pem对应的公钥已经在AWS控制台创建了密钥对,假设这个密钥对在AWS中的名称是test(名称可以自定义,但要和代码里的key_name保持一致)。test.pem确实是私钥文件,你需要把它放在Terraform代码所在的目录下(或者在代码里指定正确的文件路径)。
2. 修改Terraform代码
给每个aws_instance资源添加key_name参数,并为remote-exec配置connection块,明确SSH连接的必要信息:
provider "aws" { region = "${var.location}" } resource "aws_instance" "ins1_ec2" { ami = "${var.ami}" instance_type = "${var.inst_type}" key_name = "test" # 填写AWS中密钥对的名称,需与test.pem对应 tags = { Name = "cluster" } provisioner "remote-exec" { connection { type = "ssh" user = "centos" # CentOS默认用户名,Ubuntu用ubuntu,Amazon Linux用ec2-user private_key = file("${path.module}/test.pem") # 本地私钥文件的路径 host = self.public_ip # 直接使用实例公网IP,无需等待EIP绑定 } inline = [ "hostnamectl set-hostname centos-76-1", ] } } resource "aws_eip" "ins1_eip" { instance = "${aws_instance.ins1_ec2.id}" vpc = false } resource "aws_instance" "ins2_ec2" { ami = "${var.ami}" instance_type = "${var.inst_type}" key_name = "test" # 同样关联密钥对 tags = { Name = "cluster" } provisioner "remote-exec" { connection { type = "ssh" user = "centos" private_key = file("${path.module}/test.pem") host = self.public_ip } inline = [ "hostnamectl set-hostname centos-76-2", ] } } resource "aws_eip" "ins2_eip" { instance = "${aws_instance.ins2_ec2.id}" vpc = false }
3. 调整私钥文件权限
在执行Terraform命令前,必须确保本地test.pem的权限符合SSH要求,否则会被拒绝连接:
chmod 600 test.pem
你的疑问解答
能不能在创建EC2时使用
key_name参数?
当然可以,而且这是必须的!key_name用来关联AWS中的密钥对,没有它,EC2实例无法通过密钥登录,remote-exec自然无法建立连接。test.pem是私钥吗?
对的,.pem文件通常就是SSH私钥,对应的公钥应该已经上传到AWS并创建了密钥对,key_name就是这个密钥对在AWS中的名称。如何登录虚拟机?
EC2实例默认不支持用户名/密码登录(除非你手动配置),推荐使用密钥对登录,命令格式如下:ssh -i test.pem centos@<实例公网IP或EIP>Terraform的
aws_instance资源确实没有配置用户名/密码的选项,因为AWS官方推荐用密钥对进行身份验证,安全性更高。如果一定要用密码,需要额外通过provisioner配置,但不建议这么做。
内容的提问来源于stack exchange,提问作者learner

