
Terraform实战09ALB Target Group Auto Scaling本篇目标构建经典的Web架构ALB负载均衡器接收流量分发到Auto Scaling Group中的多台EC2实例。理解ALB、Target Group、Listener、Launch Template、ASG之间的关系。学完本篇你将掌握Application Load Balancer的创建和配置Target Group与健康检查Listener的转发规则Launch TemplateEC2实例模板Auto Scaling Group的弹性伸缩配置安全组的精细化设计ALB→EC2的单向放行前置条件已完成前八篇练习理解VPC公私网架构架构图用户浏览器 │ ▼ HTTP:80 ┌───────────────┐ │ ALB │ ← 公有子网面向外网 │ (负载均衡器) │ └───────┬───────┘ │ 转发Listener规则 ▼ ┌───────────────┐ │ Target Group │ ← 定义后端目标健康检查 └───────┬───────┘ │ 分发流量 ┌───────┴───────────────┐ │ Auto Scaling Group │ ← 私有子网 │ │ │ ┌─────┐ ┌─────┐ │ │ │EC2-1│ │EC2-2│ │ ← 根据模板自动创建 │ │:80 │ │:80 │ │ │ └─────┘ └─────┘ │ │ │ │ min1 desired2 max3│ └────────────────────────┘各组件的关系组件作用类比ALB接收外部流量分发到后端餐厅门口的领位员Listener监听哪个端口收到请求后怎么处理领位员的工作规则“80端口的客人带到Target Group”Target Group后端实例的集合健康检查规则一组可用的餐桌Launch TemplateEC2的配置模板AMI、规格、脚本餐桌的标准配置Auto Scaling Group根据模板管理EC2数量扩缩容根据客流量增减餐桌流量路径用户 → ALB(:80) → Listener(转发规则) → Target Group → EC2实例目录结构09-alb-asg/ ├── main.tf # 所有资源VPCALBTGASG ├── variables.tf # 变量实例规格、ASG数量等 └── outputs.tf # 输出ALB的DNS地址完整代码main.tfterraform { required_providers { aws { source hashicorp/aws version ~ 5.0 } } required_version 1.0 } provider aws { region var.region } locals { name_prefix ${var.project_name}-${var.environment} common_tags { Project var.project_name Environment var.environment ManagedBy terraform } # 启动脚本安装httpd显示实例ID验证负载均衡 user_data -EOF #!/bin/bash yum install -y httpd INSTANCE_ID$(curl -s http://169.254.169.254/latest/meta-data/instance-id) echo h1Hello from $INSTANCE_ID/h1pEnvironment: ${var.environment}/p /var/www/html/index.html systemctl start httpd systemctl enable httpd EOF } # VPC社区模块 module vpc { source terraform-aws-modules/vpc/aws version 5.16.0 name ${local.name_prefix}-vpc cidr 10.0.0.0/16 azs [${var.region}a, ${var.region}b] public_subnets [10.0.1.0/24, 10.0.2.0/24] private_subnets [10.0.10.0/24, 10.0.11.0/24] enable_nat_gateway true single_nat_gateway true enable_dns_hostnames true enable_dns_support true tags local.common_tags } # # 安全组设计重点 # ALB安全组允许外部HTTP # EC2安全组只允许来自ALB的流量 # resource aws_security_group alb { name ${local.name_prefix}-alb-sg vpc_id module.vpc.vpc_id ingress { description HTTP from anywhere from_port 80 to_port 80 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 merge(local.common_tags, { Name ${local.name_prefix}-alb-sg }) } resource aws_security_group ec2 { name ${local.name_prefix}-ec2-sg vpc_id module.vpc.vpc_id ingress { description HTTP from ALB only from_port 80 to_port 80 protocol tcp security_groups [aws_security_group.alb.id] # 【关键】只允许ALB安全组 } egress { from_port 0 to_port 0 protocol -1 cidr_blocks [0.0.0.0/0] } tags merge(local.common_tags, { Name ${local.name_prefix}-ec2-sg }) } # # 【新资源】ALB - Application Load Balancer # resource aws_lb web { name ${local.name_prefix}-alb internal false # 面向外网 load_balancer_type application # ALB类型 security_groups [aws_security_group.alb.id] subnets module.vpc.public_subnets # 至少2个AZ的公有子网 tags merge(local.common_tags, { Name ${local.name_prefix}-alb }) } # # 【新资源】Target Group - 后端目标组 # resource aws_lb_target_group web { name ${local.name_prefix}-tg port 80 protocol HTTP vpc_id module.vpc.vpc_id health_check { enabled true path / # 健康检查路径 port traffic-port protocol HTTP healthy_threshold 2 # 连续2次成功→健康 unhealthy_threshold 3 # 连续3次失败→不健康 timeout 5 # 超时秒数 interval 30 # 检查间隔 matcher 200 # 期望返回200 } tags merge(local.common_tags, { Name ${local.name_prefix}-tg }) } # # 【新资源】Listener - ALB监听器 # 定义收到80端口请求后转发到Target Group # resource aws_lb_listener http { load_balancer_arn aws_lb.web.arn port 80 protocol HTTP default_action { type forward target_group_arn aws_lb_target_group.web.arn } } # # 【新资源】Launch Template - EC2实例模板 # ASG根据这个模板创建新实例 # resource aws_launch_template web { name_prefix ${local.name_prefix}-lt- image_id data.aws_ami.amazon_linux.id instance_type var.instance_type vpc_security_group_ids [aws_security_group.ec2.id] user_data base64encode(local.user_data) # 启动脚本需base64编码 tag_specifications { resource_type instance tags merge(local.common_tags, { Name ${local.name_prefix}-web }) } tags merge(local.common_tags, { Name ${local.name_prefix}-launch-template }) } # # 【新资源】Auto Scaling Group - 弹性伸缩组 # resource aws_autoscaling_group web { name ${local.name_prefix}-asg desired_capacity var.desired_capacity min_size var.min_size max_size var.max_size vpc_zone_identifier module.vpc.private_subnets # EC2在私有子网 launch_template { id aws_launch_template.web.id version $Latest } # 【关键】关联Target Group新实例自动注册到ALB target_group_arns [aws_lb_target_group.web.arn] # 用ELB健康检查ALB判断实例是否健康 health_check_type ELB health_check_grace_period 60 tag { key Name value ${local.name_prefix}-web propagate_at_launch true } } data aws_ami amazon_linux { most_recent true owners [amazon] filter { name name values [al2023-ami-2023*-x86_64] } filter { name state values [available] } }variables.tfvariable region { default us-east-1 } variable project_name { default tf-practice } variable environment { default dev } variable instance_type { description EC2实例规格 default t3.micro } variable desired_capacity { description ASG期望实例数 default 2 } variable min_size { description ASG最小实例数 default 1 } variable max_size { description ASG最大实例数 default 3 }outputs.tfoutput alb_dns_name { description ALB的DNS地址浏览器访问 value aws_lb.web.dns_name } output alb_url { description 完整访问URL value http://${aws_lb.web.dns_name} } output target_group_arn { value aws_lb_target_group.web.arn } output asg_name { value aws_autoscaling_group.web.name }新增资源说明ALB关键字段字段含义internal false面向外网true内部ALBload_balancer_type applicationALB类型还有network、gatewaysecurity_groupsALB自己的安全组subnetsALB部署的子网至少2个AZTarget Group关键字段字段含义port后端实例监听的端口protocol后端使用的协议health_check.path健康检查的URL路径health_check.healthy_threshold连续几次成功算健康health_check.unhealthy_threshold连续几次失败算不健康health_check.interval检查间隔秒health_check.matcher期望的HTTP状态码Launch Template关键字段字段含义image_idAMI IDinstance_type实例规格vpc_security_group_ids安全组user_data启动脚本需base64编码tag_specifications实例标签Auto Scaling Group关键字段字段含义desired_capacity期望运行几台min_size缩容最少保留几台max_size扩容最多到几台vpc_zone_identifier实例创建在哪些子网launch_template使用哪个实例模板target_group_arns关联的Target Group新实例自动注册health_check_type“EC2或ELB”推荐ELBhealth_check_grace_period新实例启动后等多久再检查安全组设计要点外部流量 → ALB安全组允许0.0.0.0/0:80→ EC2安全组只允许ALB安全组EC2的安全组不直接开放给外网而是用security_groups [ALB的安全组ID]限制来源。这样外网只能通过ALB访问EC2直接访问EC2的公网IP会被拒绝即使EC2有公网IP也不怕事实上私有子网里没有操作步骤与实际输出Applyterraform apply -auto-approveaws_lb.web: Creation complete after 3m17s ← ALB创建较慢 aws_autoscaling_group.web: Creation complete after 14s Apply complete! Resources: 26 added, 0 changed, 0 destroyed. Outputs: alb_dns_name tf-practice-dev-alb-799249280.us-east-1.elb.amazonaws.com alb_url http://tf-practice-dev-alb-799249280.us-east-1.elb.amazonaws.com asg_name tf-practice-dev-asg验证负载均衡第1次刷新Hello from i-0abc123... 第2次刷新Hello from i-0def456... ← 不同实例负载均衡生效控制台验证ALB概览状态ActiveDNS名称类型applicationTarget Group健康状态2个实例注册状态HealthyListener规则HTTP:80 → Forward to target groupASG详情Desired: 2, Min: 1, Max: 3EC2实例2台实例由ASG创建Destroyterraform destroy -auto-approve# Destroy complete! Resources: 26 destroyed.延伸思考面试常见问题面试问题答案要点ALB和NLB的区别ALB工作在7层HTTP支持路径/域名路由NLB工作在4层TCP性能更高Target Group的健康检查有什么用自动摘除不健康的实例流量不会转发到故障节点ASG怎么实现弹性伸缩根据策略CPU利用率、请求数等自动调整desired_capacity为什么EC2安全组只允许ALB安全组最小权限原则EC2不直接暴露给外网Launch Template和Launch Configuration的区别Template更新支持版本管理、混合实例等Configuration已废弃ASG的health_check_type选EC2还是ELB推荐ELB——如果应用挂了但EC2没挂ELB能检测到EC2检测不到费用说明资源费用ALB~$0.022/小时NAT Gateway~$0.045/小时EC2 t3.micro × 2~$0.021/小时VPC / 子网 / 安全组免费总计~$0.09/小时本次练习约40分钟约$0.06小结本篇核心收获ALB Target Group ASG是AWS最经典的Web架构流量路径用户→ALB→Listener→Target Group→EC2ASG关联Target Group新实例自动注册到ALB无需手动操作安全组链式设计EC2只接受ALB的流量不直接暴露Launch TemplateEC2的模板ASG根据它创建新实例健康检查自动摘除不健康实例保证服务可用性下一篇预告Terraform实战10RDS Secrets Manager下一篇我们将学习创建RDS MySQL/PostgreSQL数据库数据库子网组配置用Secrets Manager管理数据库密码安全组限制只允许应用访问数据库参考链接本系列配套代码GitHubTerraform aws_lb文档Terraform aws_lb_target_group文档Terraform aws_autoscaling_group文档AWS ALB官方文档AWS Auto Scaling官方文档