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

AWS EC2部署Nginx遇502错误及访问超时问题求助

AWS Terraform部署Nginx+ALB出现502/访问超时问题排查与解决

问题现象

在AWS云环境通过Terraform部署EC2实例+Nginx+Application Load Balancer架构时,访问公网IP出现502错误,提示“无法访问此网站,54.155.189.11响应超时”。使用main.tf(包含VPC、子网、ALB、安全组等资源)和compute.tf(包含EC2实例、EIP、密钥对)两个配置文件,代码如下:

main.tf 配置

resource "aws_vpc" "main_vpc" {
  cidr_block       = "10.0.0.0/16"
  instance_tenancy = "default"

  tags = {
    Name = "main_vpc"
  }
}

resource "aws_subnet" "public_subnet_1" {
  vpc_id                  = aws_vpc.main_vpc.id
  cidr_block              = "10.0.1.0/24"
  availability_zone       = "eu-west-1a"
  map_public_ip_on_launch = true

  tags = {
    Name = "public_subnet_1"
  }
}

resource "aws_subnet" "public_subnet_2" {
  vpc_id                  = aws_vpc.main_vpc.id
  cidr_block              = "10.0.2.0/24"
  availability_zone       = "eu-west-1b"
  map_public_ip_on_launch = true

  tags = {
    Name = "public_subnet_2"
  }
}

resource "aws_internet_gateway" "internet_gateway" {
  vpc_id = aws_vpc.main_vpc.id

  tags = {
    Name = "internet_gateway"
  }
}

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.internet_gateway.id
  }

  tags = {
    Name = "route_table"
  }
}

# Assosiate public subnet with route table
resource "aws_route_table_association" "public_subnet_1_association" {
  subnet_id      = aws_subnet.public_subnet_1.id
  route_table_id = aws_route_table.route_table.id
}

resource "aws_route_table_association" "public_subnet_2_association" {
  subnet_id      = aws_subnet.public_subnet_2.id
  route_table_id = aws_route_table.route_table.id
}

# Create Load balancer
resource "aws_lb" "two-tier-lb" {
  name               = "two-tier-lb"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.two-tier-alb-sg.id]
  subnets            = [aws_subnet.public_subnet_1.id, aws_subnet.public_subnet_2.id]

  tags = {
    Environment = "two-tier-lb"
  }
}

resource "aws_lb_target_group" "two-tier-lb-tg" {
  name     = "two-tier-lb-tg"
  port     = 80
  protocol = "HTTP"
  vpc_id   = aws_vpc.main_vpc.id
}

# Create Load Balancer listener
resource "aws_lb_listener" "two-tier-lb-listner" {
  load_balancer_arn = aws_lb.two-tier-lb.arn
  port              = "80"
  protocol          = "HTTP"
  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.two-tier-lb-tg.arn
  }
}

# Create Target group
resource "aws_lb_target_group" "two-tier-loadb_target" {
  name       = "target"
  depends_on = [aws_vpc.main_vpc]
  port       = "80"
  protocol   = "HTTP"
  vpc_id     = aws_vpc.main_vpc.id

}

resource "aws_lb_target_group_attachment" "two-tier-tg-attch-1" {
  target_group_arn = aws_lb_target_group.two-tier-loadb_target.arn
  target_id        = aws_instance.two-tier-web-server-1.id
  port             = 80
}
resource "aws_lb_target_group_attachment" "two-tier-tg-attch-2" {
  target_group_arn = aws_lb_target_group.two-tier-loadb_target.arn
  target_id        = aws_instance.two-tier-web-server-2.id
  port             = 80
}

# Security Group
resource "aws_security_group" "two-tier-ec2-sg" {
  name        = "two-tier-ec2-sg"
  description = "Allow traffic from VPC"
  vpc_id      = aws_vpc.main_vpc.id
  depends_on = [
    aws_vpc.main_vpc
  ]

  ingress {
    from_port = "0"
    to_port   = "0"
    protocol  = "-1"
  }
  ingress {
    from_port   = "80"
    to_port     = "80"
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  ingress {
    from_port   = "22"
    to_port     = "22"
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  egress {
    from_port   = "0"
    to_port     = "0"
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "two-tier-ec2-sg"
  }
}

# Load balancer security group
resource "aws_security_group" "two-tier-alb-sg" {
  name        = "two-tier-alb-sg"
  description = "load balancer security group"
  vpc_id      = aws_vpc.main_vpc.id
  depends_on = [
    aws_vpc.main_vpc
  ]


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


  tags = {
    Name = "two-tier-alb-sg"
  }
}

compute.tf 配置

# Public subnet EC2 instance 1
resource "aws_instance" "two-tier-web-server-1" {
  ami             = "ami-0f3164307ee5d695a"
  instance_type   = "t2.micro"
  security_groups = [aws_security_group.two-tier-ec2-sg.id]
  subnet_id       = aws_subnet.public_subnet_1.id
  key_name        = aws_key_pair.key-tf.id

  tags = {
    Name = "two-tier-web-server-1"
  }

  user_data = <<-EOF
#!/bin/bash
sudo yum update -y
sudo amazon-linux-extras install nginx1 -y 
sudo systemctl enable nginx
sudo systemctl start nginx
EOF
}

# Public subnet  EC2 instance 2
resource "aws_instance" "two-tier-web-server-2" {
  ami             = "ami-0f3164307ee5d695a"
  instance_type   = "t2.micro"
  security_groups = [aws_security_group.two-tier-ec2-sg.id]
  subnet_id       = aws_subnet.public_subnet_2.id
  key_name        = aws_key_pair.key-tf.id

  tags = {
    Name = "two-tier-web-server-2"
  }

  user_data = <<-EOF
#!/bin/bash
sudo yum update -y
sudo amazon-linux-extras install nginx1 -y 
sudo systemctl enable nginx
sudo systemctl start nginx
EOF
}

#EIP

resource "aws_eip" "two-tier-web-server-1-eip" {
  vpc = true

  instance   = aws_instance.two-tier-web-server-1.id
  depends_on = [aws_internet_gateway.internet_gateway]
}

resource "aws_eip" "two-tier-web-server-2-eip" {
  vpc = true

  instance   = aws_instance.two-tier-web-server-2.id
  depends_on = [aws_internet_gateway.internet_gateway]
}

resource "aws_key_pair" "key-tf" {
  key_name   = "key-tf"
  public_key = file("/Users/roman/.ssh/id_rsa.pub")
}

问题原因

  1. ALB监听器关联错误目标组:ALB的监听器two-tier-lb-listner指向了未挂载任何EC2实例的空目标组two-tier-lb-tg,而实际挂载EC2的目标组是two-tier-loadb_target,导致ALB没有可用后端节点转发请求,返回502错误。
  2. 目标组缺失健康检查配置:默认健康检查规则可能无法正确识别Nginx的运行状态,即使实例上Nginx正常,也可能被标记为不健康,ALB同样会返回502。
  3. EC2实例Nginx启动脚本存在隐患:user_data中先执行yum update,如果该步骤因网络或镜像源问题失败,会导致后续Nginx安装和启动步骤中断,实例上Nginx未正常运行,直接访问实例IP也会超时。

解决方案

1. 修正监听器与目标组的关联

修改main.tf中的aws_lb_listener资源,将默认动作的target_group_arn改为实际挂载EC2的目标组ARN,同时删除无用的空目标组two-tier-lb-tg:

# 删除无用的空目标组
# resource "aws_lb_target_group" "two-tier-lb-tg" {
#   name     = "two-tier-lb-tg"
#   port     = 80
#   protocol = "HTTP"
#   vpc_id   = aws_vpc.main_vpc.id
# }

# 修正监听器的目标组关联
resource "aws_lb_listener" "two-tier-lb-listner" {
  load_balancer_arn = aws_lb.two-tier-lb.arn
  port              = "80"
  protocol          = "HTTP"
  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.two-tier-loadb_target.arn # 修正此处
  }
}

2. 为目标组添加健康检查配置

在two-tier-loadb_target目标组中添加适配Nginx的健康检查规则,确保ALB能正确识别实例状态:

resource "aws_lb_target_group" "two-tier-loadb_target" {
  name       = "target"
  depends_on = [aws_vpc.main_vpc]
  port       = "80"
  protocol   = "HTTP"
  vpc_id     = aws_vpc.main_vpc.id

  # 添加健康检查配置
  health_check {
    path                = "/"
    protocol            = "HTTP"
    port                = "traffic-port"
    interval            = 30
    timeout             = 5
    healthy_threshold   = 2
    unhealthy_threshold = 2
    matcher             = "200-299"
  }
}

3. 优化EC2实例的Nginx启动脚本

调整user_data逻辑,避免yum update失败影响后续步骤,同时添加状态验证日志:

#!/bin/bash
# 可选:跳过yum update以加快部署,或忽略update失败
sudo yum update -y || echo "yum update failed, proceeding with nginx installation"
sudo amazon-linux-extras install nginx1 -y 
sudo systemctl enable nginx
sudo systemctl start nginx
# 记录Nginx状态到日志,方便排查
sudo systemctl status nginx >> /var/log/nginx_setup.log

4. 验证部署状态

  • 执行terraform apply更新资源后,登录AWS控制台查看ALB目标组状态,确认EC2实例显示为健康。
  • 直接访问EC2实例的弹性公网IP,确认Nginx默认页面能正常打开,排除实例本身的问题。
  • 访问ALB的公网DNS名称,验证请求能正常转发到Nginx实例。

内容的提问来源于stack exchange,提问作者O.Man

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 23:59:51