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

Terraform部署的AWS EC2实例无法访问YUM源公网连接超时故障

背景

使用Terraform搭建AWS自动伸缩组,组内多台EC2实例分布在不同可用区,通过负载均衡器关联。所有资源均正常创建,但负载均衡器无有效目标,排查确认是实例80端口无服务监听,原计划安装NGINX并配置基础服务解决该问题。

预期行为

EC2实例可正常访问YUM软件源,执行软件包安装操作。

实际行为

实例无法ping通外部公网地址,也无法执行包管理命令,返回如下错误:

Could not retrieve mirrorlist https://amazonlinux-2-repos-us-east-2.s3.dualstack.us-east-2.amazonaws.com/2/core/latest/x86_64/mirror.list error was
12: Timeout on https://amazonlinux-2-repos-us-east-2.s3.dualstack.us-east-2.amazonaws.com/2/core/latest/x86_64/mirror.list: (28, 'Failed to connect to amazonlinux-2-repos-us-east-2.s3.dualstack.us-east-2.amazonaws.com port 443 after 2700 ms: Connection timed out')


 One of the configured repositories failed (Unknown),
 and yum doesn't have enough cached data to continue. At this point the only
 safe thing yum can do is fail. There are a few ways to work "fix" this:

     1. Contact the upstream for the repository and get them to fix the problem.

     2. Reconfigure the baseurl/etc. for the repository, to point to a working
        upstream. This is most often useful if you are using a newer
        distribution release than is supported by the repository (and the
        packages for the previous distribution release still work).

     3. Run the command with the repository temporarily disabled
            yum --disablerepo=<repoid> ...

     4. Disable the repository permanently, so yum won't use it by default. Yum
        will then just ignore the repository until you permanently enable it
        again or use --enablerepo for temporary usage:

            yum-config-manager --disable <repoid>
        or
            subscription-manager repos --disable=<repoid>

     5. Configure the failing repository to be skipped, if it is unavailable.
        Note that yum will try to contact the repo. when it runs most commands,
        so will have to try and fail each time (and thus. yum will be be much
        slower). If it is a very temporary problem though, this is often a nice
        compromise:

            yum-config-manager --save --setopt=<repoid>.skip_if_unavailable=true

Cannot find a valid baseurl for repo: amzn2-core/2/x86_64
已执行排查步骤

目前user_data自动配置功能存在问题,通过SSH连接到实例排查,实例部署在公有子网中,自动分配公网IP。以下为当前安全组配置代码:

resource "aws_security_group" "elb_webtrafic_sg" {
    name        = "elb-webtraffic-sg"
    description = "Allow inbound web trafic to load balancer"
    vpc_id      = aws_vpc.main_vpc.id
    ingress {
        description = "HTTPS trafic from vpc"
        from_port        = 443
        to_port          = 443
        protocol         = "tcp"
        cidr_blocks      = ["0.0.0.0/0"]
    }
    ingress {
        description = "HTTP trafic from vpc"
        from_port        = 80
        to_port          = 80
        protocol         = "tcp"
        cidr_blocks      = ["0.0.0.0/0"]
    }
    ingress {
        description = "allow SSH"
        from_port        = 22
        to_port          = 22
        protocol         = "tcp"
        cidr_blocks      = ["0.0.0.0/0"]
    }
    egress {
        description = "all traffic out"
        from_port        = 0
        to_port          = 0
        protocol         = "-1"
        cidr_blocks      = ["0.0.0.0/0"]
    }
    tags        = {
        Name = "elb-webtraffic-sg"
    }
}

resource "aws_security_group" "instance_sg" {
    name        = "instance-sg"
    description = "Allow traffic from load balancer to instances"
    vpc_id      = aws_vpc.main_vpc.id
    ingress {
        description = "web traffic from load balancer"
        security_groups  = [ aws_security_group.elb_webtrafic_sg.id ]
        from_port        = 80
        to_port          = 80
        protocol         = "tcp"
    }
    ingress {
        description = "web traffic from load balancer"
        security_groups  = [ aws_security_group.elb_webtrafic_sg.id ]
        from_port        = 443
        to_port          = 443
        protocol         = "tcp"
    }
    ingress {
        description = "ssh traffic from anywhere"
        from_port        = 22
        to_port          = 22
        protocol         = "tcp"
        cidr_blocks      = ["0.0.0.0/0"]
    }
    egress {
        description = "all traffic to load balancer"
        security_groups  = [ aws_security_group.elb_webtrafic_sg.id ]
        from_port        = 0
        to_port          = 0
        protocol         = "-1"
    }
    tags        = {
        Name = "instance-sg"
    }
}

#this is a workaround for the cyclical security group id call
#I would like to figure out a way for this to destroy this first
#it currently takes longer to destroy than to set up
#terraform hangs because of the dependancy each SG has on each other, 
#but will eventually struggle down to this rule and delete it, clearing the deadlock
resource "aws_security_group_rule" "elb_egress_to_webservers" {
  security_group_id        = aws_security_group.elb_webtrafic_sg.id
  type                     = "egress"
  source_security_group_id = aws_security_group.instance_sg.id
  from_port                = 80
  to_port                  = 80
  protocol                 = "tcp"
}

resource "aws_security_group_rule" "elb_tls_egress_to_webservers" {
  security_group_id        = aws_security_group.elb_webtrafic_sg.id
  type                     = "egress"
  source_security_group_id = aws_security_group.instance_sg.id
  from_port                = 443
  to_port                  = 443
  protocol                 = "tcp"
}

已确认的现象:

  • 可以正常通过SSH连接实例,曾尝试修改实例安全组入方向规则允许公网直接访问实例,但问题依旧:无法ping通外部公网地址,执行YUM命令仍返回相同错误。
  • 实例可以正常ping通各子网的默认网关:10.0.0.1、10.0.1.1、10.0.2.1。

以下为当前的路由配置代码:

resource "aws_vpc" "main_vpc" {
  cidr_block    = "10.0.0.0/16"
  tags          = {
    Name = "production-vpc"
  }
}

resource "aws_key_pair" "aws_key" {
  key_name = "Tanchwa_pc_aws"
  public_key = file(var.public_key_path)
}

#internet gateway
resource "aws_internet_gateway" "gw" {
  vpc_id = aws_vpc.main_vpc.id
  tags = {
    Name = "internet-gw"
  } 
}


resource "aws_route_table" "route_table" {
  vpc_id = aws_vpc.main_vpc.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.gw.id
  }

  tags = {
    Name = "production-route-table"
  }
}


resource "aws_subnet" "public_us_east_2a" {
  vpc_id     = aws_vpc.main_vpc.id
  cidr_block = "10.0.0.0/24"
  availability_zone = "us-east-2a"

  tags = {
    Name = "Public-Subnet us-east-2a"
  }
}

resource "aws_subnet" "public_us_east_2b" {
  vpc_id     = aws_vpc.main_vpc.id
  cidr_block = "10.0.1.0/24"
  availability_zone = "us-east-2b"

  tags = {
    Name = "Public-Subnet us-east-2b"
  }
}

resource "aws_subnet" "public_us_east_2c" {
  vpc_id     = aws_vpc.main_vpc.id
  cidr_block = "10.0.2.0/24"
  availability_zone = "us-east-2c"

  tags = {
    Name = "Public-Subnet us-east-2c"
  }
}


resource "aws_route_table_association" "a" {
    subnet_id = aws_subnet.public_us_east_2a.id
    route_table_id = aws_route_table.route_table.id
}

resource "aws_route_table_association" "b" {
    subnet_id = aws_subnet.public_us_east_2b.id
    route_table_id = aws_route_table.route_table.id
}

resource "aws_route_table_association" "c" {
    subnet_id = aws_subnet.public_us_east_2c.id
    route_table_id = aws_route_table.route_table.id
}
故障根因

核心问题出在实例关联的安全组instance_sg的出方向规则配置错误:
当前实例安全组的出方向仅允许发往ELB安全组的所有流量,没有放通实例到公网的出向访问权限。
AWS安全组是有状态规则组:入方向允许的SSH连接对应的响应流量不受出向规则限制,因此可以正常SSH连接实例;但实例主动发起的公网访问(包括ping公网、连接YUM源443端口)不属于入站规则对应的响应流量,会被出向规则拦截,导致连接超时。
路由表、互联网网关、子网关联配置均正常,不存在配置错误。

修复方案
  1. 修改instance_sg的出方向规则,将原有仅指向ELB安全组的egress规则替换为允许所有出向流量到0.0.0.0/0,配置参考如下:
    egress {
        description = "allow all outbound traffic"
        from_port        = 0
        to_port          = 0
        protocol         = "-1"
        cidr_blocks      = ["0.0.0.0/0"]
    }
    
  2. 删除配置中两个多余的aws_security_group_rule资源(elb_egress_to_webservers和elb_tls_egress_to_webservers):ELB安全组本身已经配置了全通出向规则,这两条规则完全多余,删除后即可解决两个安全组互相引用导致的循环依赖、Terraform销毁卡顿问题。
  3. 执行terraform apply更新配置后,无需重启实例,等待安全组规则生效(通常10秒内),即可正常执行yum安装、ping公网等操作。

内容的提问来源于stack exchange,提问作者Tanchwa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 22:18:23