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") }
问题原因
- ALB监听器关联错误目标组:ALB的监听器
two-tier-lb-listner指向了未挂载任何EC2实例的空目标组two-tier-lb-tg,而实际挂载EC2的目标组是two-tier-loadb_target,导致ALB没有可用后端节点转发请求,返回502错误。 - 目标组缺失健康检查配置:默认健康检查规则可能无法正确识别Nginx的运行状态,即使实例上Nginx正常,也可能被标记为不健康,ALB同样会返回502。
- 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
相关产品推荐
相关产品推荐

