AWS Auto Scaling CodeDeploy默认钩子失败时终止实例的解决办法咨询
解决CodeDeploy部署失败时EC2实例被终止的问题
核心原因
当Auto Scaling组与CodeDeploy集成时,默认会创建CodeDeploy托管的生命周期钩子,同时部署组默认启用“部署失败时终止Auto Scaling组中的实例”选项。无论钩子默认结果设为ABANDON还是CONTINUE,部署失败或手动停止时,CodeDeploy都会主动调用CompleteLifecycleAction传入ABANDON,并触发实例终止操作,这就是问题的根源。
解决方案
1. 关闭CodeDeploy部署组的自动终止功能
- 登录CodeDeploy控制台,定位到目标部署组
- 进入编辑页面,找到**“部署失败时终止Auto Scaling组中的实例”**选项,取消勾选
- 保存配置
2. 替换默认的CodeDeploy托管生命周期钩子
默认托管钩子由CodeDeploy自动管控,无法自定义行为,需删除后手动创建自定义钩子:
- 打开Auto Scaling控制台,进入目标ASG的“生命周期钩子”标签页
- 删除名称以
CodeDeploy-managed-automatic-launch-deployment-hook-开头的默认钩子 - 创建新钩子:
- 名称:自定义命名(如
Custom-Launch-Deployment-Hook) - 生命周期转换:选择
autoscaling:EC2_INSTANCE_LAUNCHING - 默认结果:设为
CONTINUE(避免超时后实例被自动终止) - 心跳超时:根据实际部署时长设置,建议设为
3600秒(1小时,预留足够排查时间) - 通知目标:可复用原有SQS队列,或配置Lambda函数实现动态处理
- 名称:自定义命名(如
3. 自定义钩子事件处理(可选,精细化控制)
若需根据部署状态动态决策,可通过Lambda监听SQS钩子通知,实现以下逻辑:
- 解析SQS消息中的实例ID、钩子名称、ASG名称及部署ID(需在钩子配置中传入部署ID作为元数据)
- 调用CodeDeploy
GetDeploymentAPI查询部署状态 - 若部署状态为
FAILED或STOPPED,调用Auto ScalingCompleteLifecycleActionAPI传入CONTINUE,保留实例 - 若部署成功,同样传入
CONTINUE,让实例正常加入ASG
示例Python Lambda代码:
import boto3 import json autoscaling_client = boto3.client('autoscaling') codedeploy_client = boto3.client('codedeploy') def lambda_handler(event, context): for record in event['Records']: message = json.loads(record['body']) instance_id = message['EC2InstanceId'] hook_name = message['LifecycleHookName'] asg_name = message['AutoScalingGroupName'] deployment_id = message.get('NotificationMetadata') if not deployment_id: continue # 获取部署状态 deployment_response = codedeploy_client.get_deployment(deploymentId=deployment_id) deployment_status = deployment_response['deploymentInfo']['status'] # 根据状态完成生命周期动作 autoscaling_client.complete_lifecycle_action( LifecycleHookName=hook_name, AutoScalingGroupName=asg_name, LifecycleActionResult='CONTINUE', InstanceId=instance_id )
验证
- 触发ASG实例启动或CodeDeploy部署
- 人为制造部署失败(如在部署脚本中加入错误指令)
- 检查EC2控制台,确认实例未被终止且处于运行状态
内容的提问来源于stack exchange,提问作者Nipun Sharma
相关产品推荐
相关产品推荐

