【问题标题】:Terraform EC2 networking brokenTerraform EC2 网络中断
【发布时间】:2020-10-10 08:08:54
【问题描述】:

我正在使用 Terraform 0.12.26,我想构建一个 AWS Ubuntu 机器实例。

当我运行terraform apply 时,一切看起来都正常……但我无法通过 ssh 连接到新的 EC2 机器。我的家庭防火墙允许在任何地方使用 ssh,我可以通过 ssh 访问任何其他互联网资源。

如果我在同一区域/az 中手动安装 EC2 实例,ssh 可以正常工作...这个问题似乎仅限于 Terraform。

$ terraform apply
...
Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_key_pair.mykeypair: Creating...
aws_vpc.main: Creating...
aws_key_pair.mykeypair: Creation complete after 2s [id=mykeypair-pub]
aws_vpc.main: Still creating... [10s elapsed]
aws_vpc.main: Creation complete after 14s [id=vpc-0396212cf58236e68]
aws_subnet.first_subnet: Creating...
aws_security_group.ingress-policy-example: Creating...
aws_subnet.first_subnet: Creation complete after 10s [id=subnet-0558eb0d5c2a4cb3e]
aws_security_group.ingress-policy-example: Still creating... [10s elapsed]
aws_security_group.ingress-policy-example: Creation complete after 13s [id=sg-080e7fa96dc485107]
aws_instance.example: Creating...
aws_instance.example: Still creating... [10s elapsed]
aws_instance.example: Still creating... [20s elapsed]
aws_instance.example: Creation complete after 25s [id=i-0aaf3c53023c1226f]

Apply complete! Resources: 5 added, 0 changed, 0 destroyed.

Outputs:

ip = 34.217.88.173

$ telnet 34.217.88.173 22
Trying 34.217.88.173...
telnet: Unable to connect to remote host: Resource temporarily unavailable
$

这是我的 terraform 代码:​​

$ cat main.tf
provider "aws" {
  region     = var.region
  access_key = "SECRET_ACCESS_KEY_HERE"
  secret_key = "SECRET_KEY_HERE"

  # Allow any 2.x version of the AWS provider
  version = "~> 2.0"
}

variable region {
  default = "us-west-2"
}

variable availability_zone_01 {
  default = "us-west-2a"
}

variable key_path {
    default = "~/.ssh/id_rsa.pub"
}

variable site_supernet {
    default = "10.0.0.0/16"
}

variable first_subnet {
    default = "10.0.1.0/24"
}

resource "aws_vpc" "main" {
  cidr_block           = var.site_supernet
  enable_dns_hostnames = true
  enable_dns_support   = true
  instance_tenancy     = "default"

  tags = {
    Name = "tag-primary-vpc"
  }
}

resource "aws_subnet" "first_subnet" {
  vpc_id                  = aws_vpc.main.id
  cidr_block              = var.first_subnet
  availability_zone       = var.availability_zone_01
  map_public_ip_on_launch = true

  tags = {
    Name = "tag-first_subnet"
  }
}

resource "aws_security_group" "ingress-policy-example" {
  vpc_id        = aws_vpc.main.id
  ingress {
    cidr_blocks = ["0.0.0.0/0",]
    from_port   = 22  # Port from 22 to 22...
    to_port     = 22
    protocol    = "tcp"
  }

  ## This egress rule was missing from my original question...
  egress {
    # Terraform doesn't allow all egress traffic by default...
    cidr_blocks = ["0.0.0.0/0"]
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
  }

  tags = {
    Name = "tag-sg-allow-ssh"
  }
}

resource "aws_key_pair" "mykeypair" {
  key_name   = "mykeypair-pub"
  public_key = file(var.key_path)
}

resource "aws_instance" "example" {
  #ami           = "ami-0994c095691a46fb5"
  ami           = "ami-003634241a8fcdec0"
  instance_type = "t2.nano"
  key_name      = aws_key_pair.mykeypair.key_name

  subnet_id                   = aws_subnet.first_subnet.id
  vpc_security_group_ids      = [
    aws_security_group.ingress-policy-example.id,
  ]
  associate_public_ip_address = true

  root_block_device {
    delete_on_termination = false
  }

  user_data = <<-EOF
              #!/bin/bash
              apt-get update
              apt-get install openssh-server
              EOF

  tags = {
    Name = "stackoverflow_20200619"
  }
}

output "ip" {
  value = aws_instance.example.public_ip
}

问题:如何修复这个 terraform 部署,以便可以通过 ssh 连接到上面的服务器?

我的尝试

  • 使用密钥验证手动构建 Ubuntu 映像;这很好用,我可以通过 ssh 访问它
  • 移除 terraform 安全组;没有帮助
  • 更改了 AWS terraform 区域/可用区;没有帮助
  • 删除user_data包安装;没有帮助
  • 删除aws_subnet;没有帮助
  • 删除instance_tenancy;没有帮助
  • 用另一个 ssh 密钥替换 ssh 密钥;没有帮助
  • 用静态用户名/密码替换 ssh 密钥;没有帮助
  • 从 Windows 使用 PuTTY(而不是 linux 和 openssh)进行 SSH;没有帮助

【问题讨论】:

  • 您可能希望删除其中对 telnet 的引用。我最初认为这可能是你的问题。此外,除非您使用特别奇特的东西,否则 openssh-server 在适用于 Linux 发行版的 AWS EC2 AMI 上普遍预配置得非常好,因此您也可以删除 user_data。
  • @AlainO'Dea,telnet somehostname 22 只是nmap -p 22 somehostname 的另一种方式。
  • 公平。这是一个健全性检查,您可以获得 TCP 连接。有效点!

标签: amazon-web-services amazon-ec2 terraform terraform-provider-aws


【解决方案1】:

您的 VPC 没有互联网网关 (IGW)。您需要创建它并为其添加一个路由表条目。

添加这些资源应该可以工作(在我的手机上写了这个,所以你的里程可能会有所不同):

resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.main.id

  tags = {
    Name = "main"
  }
}

resource "aws_route" "r" {
  route_table_id            = aws_route_table.rt
  destination_cidr_block    = "0.0.0.0/0"
  gateway_id = aws_internet_gateway.igw.id
}

resource "aws_route_table" "rt" {
  vpc_id = aws_vpc.main.id
}

resource "aws_route_table_association" "rta" {
  subnet_id      = aws_subnet.first_subnet.id
  route_table_id = aws_route_table.rt.id
}

【讨论】:

  • 您的回答很有帮助,但缺少一个关键部分:除了您在这里拥有的内容之外,我还需要添加一个 egress 规则,允许从我的实例到互联网的所有内容(参考:@987654321 @:关于出口规则的注意事项:默认情况下,AWS 在 VPC 内创建新安全组时会创建一个 ALLOW ALL 出口规则。在 VPC 内创建新安全组时,Terraform 将删除此默认规则,并要求如果您需要该规则,您可以专门重新创建它。)。我将那篇文章编辑到我的问题中
  • 太棒了。我很高兴它有帮助。不过,我对出口规则很好奇。安全组是有状态的,因此默认情况下它们应该允许回复流量。通常,您只需要在入口规则上允许 SSH,就足以让 SSH 工作。但是,如果没有该出口规则,它不会允许实例运行更新或启动自己的连接,因此值得从允许所有流量出口的地方开始。
  • 我找不到解释安全组是否有状态的权威 AWS 安全组参考。但是,我的测试很明显,除非我包含允许所有出口规则,否则我无法在端口 22 上与新 EC2 机器建立 tcp 连接。当我 ssh 进入时,我还检查了 EC2 是否在我的源 IP 上进行 DNS 反向查找;但是,EC2 没有进行 IP 查找(因此如果 DNS 超时,则不会遭受初始 ssh 连接延迟)。
  • 我尝试从 AWS 文档中复制粘贴文本,但我在手机上,iOS 应用程序不允许我将其粘贴到评论中。 AWS 用这个来掩埋这个问题。当我查看安全组基础知识时,我在下面的几个项目中发现“安全组是有状态的......”。 docs.aws.amazon.com/vpc/latest/userguide/…
  • 你说得对,文档说安全组规则默认是有状态的(有一些例外);但是,他们的行为在我的 ssh 测试中显然不是有状态的(如果我删除了我的 egress 规则)。也许我遇到了错误?
猜你喜欢
  • 2011-12-11
  • 2018-07-11
  • 1970-01-01
  • 1970-01-01
  • 2021-03-17
  • 2021-05-15
  • 2018-12-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多