如何用Terraform实现CodeDeploy与Auto Scaling Groups的可重复蓝绿部署
蓝绿部署+单EC2实例持续部署解决方案(Terraform+AWS CodeDeploy)
问题核心
要实现:基于Terraform托管的基础设施,用AWS CodeDeploy做蓝绿部署Web API,每次仅运行1个EC2实例,同时支持持续重复部署;当前用DISCOVER_EXISTING模式+两个固定ASG的方案,首次部署后ASG角色互换,无可用绿色组导致后续部署失败。
可行方案
1. 调整Terraform基础设施配置
- 维护两个配置完全一致的Auto Scaling Group(简称ASG),命名为
asg-blue和asg-green,初始时设置其中一个desired_capacity = 1,另一个desired_capacity = 0 - 在CodeDeploy部署组资源中,配置
green_fleet_provisioning_option = { action = "DISCOVER_EXISTING" },并将两个ASG都关联到部署组(而非仅指定单个目标ASG) - 开启蓝绿部署的自动终止配置:设置
blue_green_deployment_config.terminate_blue_instances_on_deployment_success = "TERMINATE",按需配置termination_wait_time_in_minutes
2. 修改部署触发逻辑(GitHub Action)
不再固定指定目标ASG,而是动态识别当前容量为0的ASG作为绿色组,示例命令如下:
# 第一步:查询当前容量为0的ASG(假设两个ASG前缀为my-api-) GREEN_ASG=$(aws autoscaling describe-auto-scaling-groups \ --auto-scaling-group-names my-api-blue my-api-green \ --region <region> \ | jq -r '.AutoScalingGroups[] | select(.DesiredCapacity == 0) | .AutoScalingGroupName') # 第二步:触发CodeDeploy部署,指定动态获取的绿色ASG aws deploy create-deployment \ --application-name <app_name> \ --s3-location bucket=<bucket_Name>,key=revision_LATEST.zip,bundleType=zip \ --deployment-group-name <deployment_group_name> \ --deployment-config-name CodeDeployDefault.AllAtOnce \ --description "My description" \ --region <region> \ --target-instances="{\"autoScalingGroups\":[\"$GREEN_ASG\"]}"
说明:单实例场景下,用
CodeDeployDefault.AllAtOnce部署配置更高效,无需分批等待。
3. 部署后同步ASG容量状态
在CodeDeploy部署成功、流量切换完成后,将原蓝色ASG(当前容量为1)的期望容量设为0,新绿色ASG设为1,示例脚本:
# 查询当前容量为1的ASG(原蓝色组)和容量为0的ASG(新绿色组) BLUE_ASG=$(aws autoscaling describe-auto-scaling-groups \ --auto-scaling-group-names my-api-blue my-api-green \ --region <region> \ | jq -r '.AutoScalingGroups[] | select(.DesiredCapacity == 1) | .AutoScalingGroupName') GREEN_ASG=$(aws autoscaling describe-auto-scaling-groups \ --auto-scaling-group-names my-api-blue my-api-green \ --region <region> \ | jq -r '.AutoScalingGroups[] | select(.DesiredCapacity == 0) | .AutoScalingGroupName') # 调整容量状态,为下一次部署做准备 aws autoscaling update-auto-scaling-group \ --auto-scaling-group-name $BLUE_ASG \ --desired-capacity 0 \ --region <region> aws autoscaling update-auto-scaling-group \ --auto-scaling-group-name $GREEN_ASG \ --desired-capacity 1 \ --region <region>
4. 关键注意事项
- 两个ASG的配置必须完全一致(实例类型、AMI、安全组、负载均衡目标组关联等),避免部署差异
- Terraform中需将ASG的
desired_capacity设为可变参数(比如通过var定义),允许外部脚本或Action动态调整,不要硬编码 - 确保CodeDeploy部署组的
traffic_routing_config正确关联负载均衡的目标组,保证流量切换正常
可行性结论
完全可行。核心逻辑是通过动态切换两个ASG的容量状态,配合CodeDeploy的DISCOVER_EXISTING模式,既避免了CodeDeploy创建Terraform未托管ASG的冲突问题,又能保证每次仅运行一个EC2实例,同时支持持续重复的蓝绿部署。
内容的提问来源于stack exchange,提问作者Timothy G.
相关产品推荐
相关产品推荐

