【问题标题】:EC2 instance i-####### is not in the same VPC as ELB using TerraformEC2 实例 i-####### 与使用 Terraform 的 ELB 不在同一个 VPC 中
【发布时间】:2021-11-05 04:40:50
【问题描述】:

我在使用 Terraform 进行测试时遇到问题。我是 AWS 和 Terraform 技术的新手。我正在尝试在负载均衡器下创建一些网络服务器。

为了实现这一点,我创建了:

VPC、子网、互联网网关和路由表:

resource "aws_vpc" "vpc" {
  cidr_block = "${var.cidr}"
  enable_dns_hostnames = false
  enable_dns_support = false
  tags = {
    Name = "vpc-${var.project}"
  }
}

resource "aws_subnet" "pub1" {
  cidr_block = "${var.pub1_cidr}"
  vpc_id = "${aws_vpc.vpc.id}"
  map_public_ip_on_launch = true
  availability_zone = "${data.aws_availability_zones.az.names[0]}"
  tags = {
    Name = "${var.project}-subnetpub1"
  }
}

resource "aws_subnet" "pub2" {
  cidr_block = "${var.pub2_cidr}"
  vpc_id = "${aws_vpc.vpc.id}"
  map_public_ip_on_launch = true
  availability_zone = "${data.aws_availability_zones.az.names[1]}"
  tags = {
    Name = "${var.project}-subnetpub2"
  }
}

resource "aws_subnet" "pri1" {
  cidr_block = "${var.pri1_cidr}"
  vpc_id = "${aws_vpc.vpc.id}"
  map_public_ip_on_launch = true
  availability_zone = "${data.aws_availability_zones.az.names[0]}"
  tags = {
    Name = "${var.project}-subnet1"
  }
}

resource "aws_subnet" "pri2" {
  cidr_block = "${var.pri2_cidr}"
  vpc_id = "${aws_vpc.vpc.id}"
  map_public_ip_on_launch = true
  availability_zone = "${data.aws_availability_zones.az.names[1]}"
  tags = {
    Name = "${var.project}-subnet2"
  }
}

resource "aws_internet_gateway" "igw" {
  vpc_id = "${aws_vpc.vpc.id}"
}

resource "aws_route" "default_route" {
  route_table_id = "${aws_vpc.vpc.default_route_table_id}"
  destination_cidr_block = "0.0.0.0/0"
  gateway_id = "${aws_internet_gateway.igw.id}"
}

安全组:

resource "aws_security_group" "elb-sg" {
  name = "elb-sg"
  vpc_id = aws_vpc.vpc.id

  # Entrada
  ingress {
    from_port = 80
    protocol = "tcp"
    to_port = 80
    cidr_blocks = ["0.0.0.0/0"]
  }

  # Salida
  egress {
    from_port = 0
    protocol = "-1"
    to_port = 0
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_security_group" "elb-web" {
  name = "web-sg"
  vpc_id = aws_vpc.vpc.id

  ingress {
    from_port = 80
    protocol = "tcp"
    to_port = 80

    # Permitimos el acceso a este security group a aquellos recursos que tengan asigando el security group de elb
    security_groups = ["${aws_security_group.elb-sg.id}"]
  }
  egress {
    from_port = 0
    protocol = "-1"
    to_port = 0
    cidr_blocks = ["0.0.0.0/0"]
  }
}

最后是 ELB 和 EC2 实例:

resource "aws_elb" "elbweb" {
  name = "elb-${var.project}-${var.environment}" # Nombre del balanceador.
  cross_zone_load_balancing = true # Balancear entre las zonas
  subnets = ["${aws_subnet.pub1.id}","${aws_subnet.pub2.id}"]
  security_groups = ["${aws_security_group.elb-sg.id}"]

  listener {
    instance_port = 80
    instance_protocol = "http"
    lb_port = 80
    lb_protocol = "http"
  }

  availability_zones = "${data.aws_availability_zones.az.names}"
  instances = "${aws_instance.webservers.*.id}"
}

resource "aws_instance" "webservers" {
  instance_type = "${var.instance_type}"
  ami = "${lookup(var.aws_amis, var.region)}"
  vpc_security_group_ids = ["${aws_security_group.elb-web.id}"]
  subnet_id = "${aws_subnet.pri1.id}"

  count = 3

  tags = {
    Name = "VM${var.environment}WEBSERVER${count.index}"
  }
}

当我尝试apply 时,我收到以下错误:

aws_elb.elbweb: Modifying... [id=elb-web-project-development]
╷
│ Error: Failure registering instances with ELB: InvalidInstance: EC2 instance i-0a39df0625ab87dd1 is not in the same VPC as ELB.
│       status code: 400, request id: c0f700b4-50a7-42af-af9a-a5690509b6cb
│ 
│   with aws_elb.elbweb,
│   on elb.tf line 1, in resource "aws_elb" "elbweb":
│    1: resource "aws_elb" "elbweb" {
│ 
╵

谁能帮帮我?

【问题讨论】:

  • 你真的想使用ELB classic吗?如果你在它后面运行一个网络服务器,正常的做法是使用application load balancer,它使用aws_lb resource
  • 你的代码也有很多不必要的插值(例如"${var.instance_type}"而不是var.instance_type)。您是否从非常古老的指南中复制内容?您的错误消息看起来像是您使用的是新版本的 Terraform,并且您已将其标记为 terraform0.12+,这表明您没有使用早于 0.12 的 Terraform 版本,因此您可以放弃该插值。 terraform fmt 应该使用新版本的 Terraform 为您处理这个问题
  • @ydaetskcoR 是的,我使用的是旧文档,但我认为这不是问题,我正在学习,对于基本概念,我认为已经足够了。我会审查你告诉我的。无论如何,我不理解反对票
  • 反对票不是来自我。这个问题有很多信息,所以我不会反对。不过,我对使用一个长期弃用的东西(经典的负载均衡器)和现在学习 Terraform 的 0.12 之前的语法感到困惑。如果您想学习 Terraform,我可能会从较新的指南/资源开始。我推荐learn.hashicorp.com/terraform
  • 无论如何,我认为错误表明 ELB 和实例都已创建,但它只是无法附加实例。在这种情况下,您应该能够使用 AWS CLI(例如 aws ec2 describe-instances --instance-ids ...aws elbv2 describe-load-balancers --load-balancer-arns ...)来描述它们并编辑您的问题以包含这些输出。

标签: amazon-web-services terraform terraform-provider-aws terraform0.12+


【解决方案1】:

您需要创建一个资源aws_lb_target_group,然后创建另一个资源aws_lb_target_group_attachment,并附加实例。

此外,资源elbweb 应该有一个默认操作,将侦听器指向目标组。

查看资源pri1pri2 的代码,这些子网是专用的吗?如果是,属性map_public_ip_on_launch不应该设置为false吗?

更新:

想通了。对不起,因为我很忙,所以花了我一段时间。 我运行了您发布的代码。遇到同样的错误... not in the same VPC..,但我在调整后使代码工作。

您可以将资源aws_elbcross_zone_load_balancing 中的availability_zones 注释掉。这对我有用。

resource "aws_elb" "elb_web" {
  name                      = "elb-${var.project_name}"
  subnets                   = [aws_subnet.pub1.id, aws_subnet.pub2.id]
  security_groups           = [aws_security_group.elb-sg.id]
  # cross_zone_load_balancing = true

  listener {
    instance_port     = 80
    instance_protocol = "http"
    lb_port           = 80
    lb_protocol       = "http"
  }

  # availability_zones = []
  instances            = aws_instance.webservers.*.id
}

根据 Terraform 文档,对于资源 aws_elbcross_zone_load_balancing 默认为 true。因此,您不必将属性显式设置为true。由于启用了此属性,我假设指定 availability_zones 会导致混淆。

我在私有子网中使用两个 EC2 运行,我可以看到它们都连接到 ELB。

我希望这对你有用。

【讨论】:

  • 他们正在使用 ELB 经典(请参阅问题中的aws_elb)。
  • 哦,好吧。我的错。我会尽快给您回复。谢谢!
  • 更新了我的答案。在此处评论时不确定代码的格式。所以,请检查一下。而且,这是一个好问题!从中学到了一些新东西:)
【解决方案2】:

每列的宽度为 150 像素。这很好。 assurance chien

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-13
    • 1970-01-01
    • 2014-04-27
    • 2018-04-02
    • 2020-05-29
    • 2019-12-25
    • 1970-01-01
    • 2019-06-16
    相关资源
    最近更新 更多