如何为含混合实例策略的Auto Scaling Group配置可靠等待逻辑?
混合实例策略Auto Scaling Group的CloudFormation等待逻辑配置方案
针对混合实例策略的ASG无法使用固定实例计数CreationPolicy的问题,有以下几种可靠的配置方式:
方法一:移除固定Count,等待所有实例发送信号
直接调整CreationPolicy配置,删除Count参数。CloudFormation会自动等待ASG中所有进入InService状态的实例发送信号,无需关注具体实例数量。
示例配置:
MyMixedASG: Type: AWS::AutoScaling::AutoScalingGroup Properties: MixedInstancesPolicy: LaunchTemplate: # 你的启动模板配置 Overrides: - InstanceType: c5.18xlarge WeightedCapacity: '18' - InstanceType: c5.24xlarge WeightedCapacity: '24' - InstanceType: c5.2xlarge WeightedCapacity: '2' - InstanceType: c5.4xlarge WeightedCapacity: '4' DesiredCapacity: '24' # 目标总加权容量 # 其他ASG基础配置... CreationPolicy: ResourceSignal: Timeout: "PT15M" # 15分钟等待超时
注意事项
- 必须确保所有实例在初始化完成后,通过
cfn-signal工具向CloudFormation发送信号(脚本逻辑要兼容所有实例类型)。 - 该方式依赖ASG的生命周期管理,只要所有实例成功进入InService并发送信号,CloudFormation就会继续部署后续依赖资源。
方法二:自定义资源+Lambda验证总加权容量
如果需要严格确保ASG的总加权容量达到预期值(而非仅所有实例发信号),可以用Lambda函数作为自定义资源,验证加权容量总和后再通知CloudFormation。
步骤1:创建Lambda验证函数
该函数会轮询ASG实例状态,统计所有InService实例的加权容量之和,达标后发送完成信号:
ASGWeightedCapacityWaiter: Type: AWS::Lambda::Function Properties: Runtime: python3.11 Handler: index.lambda_handler Role: !GetAtt LambdaExecutionRole.Arn Code: ZipFile: | import boto3 import cfnresponse import time autoscaling_client = boto3.client('autoscaling') def lambda_handler(event, context): try: asg_name = event['ResourceProperties']['ASGName'] target_capacity = int(event['ResourceProperties']['TargetCapacity']) timeout_sec = int(event['ResourceProperties']['TimeoutSeconds']) start_time = time.time() while time.time() - start_time < timeout_sec: # 获取ASG详情 asg_response = autoscaling_client.describe_auto_scaling_groups( AutoScalingGroupNames=[asg_name] ) asg = asg_response['AutoScalingGroups'][0] # 构建实例类型-权重映射 instance_weight_map = { o['InstanceType']: int(o['WeightedCapacity']) for o in asg['MixedInstancesPolicy']['LaunchTemplate']['Overrides'] } # 统计当前总加权容量 current_weighted = 0 for instance in asg['Instances']: if instance['LifecycleState'] == 'InService': current_weighted += instance_weight_map.get(instance['InstanceType'], 0) if current_weighted == target_capacity: cfnresponse.send(event, context, cfnresponse.SUCCESS, {}) return time.sleep(30) # 每30秒轮询一次 # 超时未达标 cfnresponse.send( event, context, cfnresponse.FAILED, {'Message': f'超时未达到目标加权容量{target_capacity}'} ) except Exception as e: cfnresponse.send( event, context, cfnresponse.FAILED, {'Message': f'验证失败:{str(e)}'} )
步骤2:定义自定义资源并关联ASG
创建自定义资源,让CloudFormation等待该资源完成后再部署依赖项:
WaitForASGCapacity: Type: AWS::CloudFormation::CustomResource Properties: ServiceToken: !GetAtt ASGWeightedCapacityWaiter.Arn ASGName: !Ref MyMixedASG TargetCapacity: !Ref MyDesiredCapacity # 与ASG的DesiredCapacity保持一致 TimeoutSeconds: 900 # 15分钟超时 DependsOn: MyMixedASG # 依赖ASG的资源,改为依赖自定义资源 DependentResource: Type: AWS::EC2::SecurityGroup # 示例依赖资源 Properties: # 资源配置... DependsOn: WaitForASGCapacity
方法三:CloudWatch Alarm触发信号(可选)
通过CloudWatch监控ASG的加权容量指标,当GroupInServiceCapacity等于GroupDesiredCapacity时,触发Lambda发送CloudFormation信号。这种方式适合需要联动监控告警的场景,但配置相对复杂。
内容的提问来源于stack exchange,提问作者XZen
相关产品推荐
相关产品推荐

