无法使用私钥连接到 Terraform 创建的实例,但在控制台中创建实例时可以连接

Can't connect to Terraform-created instance with Private Key, but CAN connect when I create instance in Console

我使用 Terraform 创建了以下密钥对和 EC2 实例。我将不使用 SG 配置,但它允许通过互联网使用 SSH。

当我尝试通过 SSH 连接到此实例时,出现错误“服务器拒绝了我们的密钥”和“没有可用的受支持的身份验证方法(服务器发送:公钥)”。

但是 当我在控制台中创建一个单独的 EC2 实例并为其分配相同的密钥对时,我 能够登录TF 脚本。

有人见过这种行为吗?是什么原因造成的?

# Create   Dev VPC
resource "aws_vpc" "dev_vpc" {
  cidr_block       = "10.0.0.0/16"
  instance_tenancy = "default"
  enable_dns_hostnames = "true"

  tags = {
    Name = "dev"
  }
}

# Create an Internet Gateway Resource
resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.dev_vpc.id

  tags = {
    Name = "dev-engineering-igw"
  }
}

# Create a Route Table
resource "aws_route_table" " _dev_public_routes" {
  vpc_id = aws_vpc. _dev.id
  tags = {
    name = " _dev_public_routes"
  }
}

# Create a Route
resource "aws_route" " _dev_internet_access" {
  route_table_id = aws_route_table. _dev_public_routes.id
  destination_cidr_block = "0.0.0.0/0"
  gateway_id = aws_internet_gateway.igw.id
}

# Associate the Route Table to our Public Subnet
resource "aws_route_table_association" " _dev_public_subnet_assoc" {
  subnet_id = aws_subnet. _dev_public.id
  route_table_id = aws_route_table. _dev_public_routes.id
}

# Create public subnet for hosting customer-facing Django app
resource "aws_subnet" " _dev_public" {
  vpc_id            = aws_vpc. _dev.id
  cidr_block        = "10.0.0.0/17"
  availability_zone = "us-west-2a"

  tags = {
    Env = "dev"
  }
}

resource "aws_security_group" "allow_https" {
  name        = "allow_https"
  description = "Allow http and https inbound traffic"
  vpc_id      = aws_vpc. _dev.id

  ingress {
    description      = "HTTP and HTTPS into VPC"
    from_port        = 80
    to_port          = 80
    protocol         = "tcp"
    cidr_blocks      = ["0.0.0.0/0"]
  }

  ingress {
    description      = "HTTP and HTTPS into VPC"
    from_port        = 443
    to_port          = 443
    protocol         = "tcp"
    cidr_blocks      = ["0.0.0.0/0"]
  }

  ingress {
    description      = "SSH"
    from_port        = 22
    to_port          = 22
    protocol         = "tcp"
    cidr_blocks      = ["0.0.0.0/0"]
  }

    egress {
    description      = "HTTP and HTTPS out of VPC for Session Manager"
    from_port        = 443
    to_port          = 443
    protocol         = "tcp"
    cidr_blocks      = ["0.0.0.0/0"]
  }

  tags = {
    Name = "allow_https"
  }
}

resource "aws_instance" "web" {
  ami           = data.aws_ami.ubuntu20.id
  instance_type = "t3.micro"
  subnet_id = aws_subnet. _dev_public.id
  associate_public_ip_address = "true"
  vpc_security_group_ids = ["${aws_security_group.allow_https.id}"]
  key_name = "key_name"


  metadata_options { #Enabling IMDSv2
    http_endpoint = "disabled"
    http_tokens = "required"
  }

  tags = {
    Env = "dev"
  }
}

如评论中所述,从实例资源中删除 metadata_options 可解决问题。

修复方法是将 metadata_options 更新为:

  metadata_options { #Enabling IMDSv2
    http_endpoint = "enabled"
    http_tokens = "required"
  }

查看 metadata_options 的 Terraform 文档表明:

  • http_endpoint = "disabled"表示元数据服务不可用。
  • http_tokens = "required" 表示元数据服务需要会话令牌(即 IMDSv2)。

这是一个无效的配置,如 AWS docs 中所指定:

You can opt in to require that IMDSv2 is used when requesting instance metadata. Use the modify-instance-metadata-options CLI command and set the http-tokens parameter to required. When you specify a value for http-tokens, you must also set http-endpoint to enabled.