You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Terraform创建AWS EC2实例遇SSH握手失败及密钥使用问题求助

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:06:32