You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过CloudFormation更新关联LaunchTemplate的AutoScaling组

答复

1. 需求合理性与CloudFormation正确实现方式

你的更新需求完全合理,之前改UserData不生效、改LaunchTemplate名触发回滚都是配置存在疏漏,根本不需要单独找什么AWS::EC2::LaunchTemplateVersion资源——你在CloudFormation里修改AWS::EC2::LaunchTemplate下的LaunchTemplateData内容时,CloudFormation会自动创建新的LaunchTemplate版本,不用手动调CLI创建。
之前改完UserData实例没更新,核心是两个配置错误:

  • 你给ASG配的UpdatePolicy只开了AutoScalingReplacingUpdate.WillReplace=true,这个配置只有在整个ASG资源被替换重建的时候才会触发新实例创建。你只是改了关联的LaunchTemplate内容,ASG资源本身没被替换,哪怕引用的版本号变了,也不会自动触发实例滚动替换,跑的自然还是几个月前的旧实例。
  • 你配的cfn-hup监听路径写错了,运行中的实例根本收不到配置更新的触发信号。

要实现正常更新只需要做两个调整:
第一,给ASG补全滚动更新策略,把原来只配ReplacingUpdate的UpdatePolicy块替换成下面的内容,参数可以根据你的环境调整:

UpdatePolicy:
  AutoScalingRollingUpdate:
    MinInstancesInService: 0 # 生产环境建议至少设1,保证更新时服务不中断
    MaxBatchSize: 1 # 每次替换的实例数量,集群规模大可以适当调大
    MinSuccessfulInstancesPercent: 100
    PauseTime: PT15M
    WaitOnResourceSignals: true
  AutoScalingReplacingUpdate:
    WillReplace: true

第二,修正cfn-hup的配置错误,你现在/etc/cfn/hooks.d/cfn-auto-reloader.conf里写的监听路径是Resources.EC2.Metadata.AWS::CloudFormation::Init,但你模板里LaunchTemplate的逻辑ID是ec2LaunchTemplate,正确路径应该是Resources.ec2LaunchTemplate.Metadata.AWS::CloudFormation::Init。路径写错的话cfn-hup根本监听不到元数据变化,不会自动执行cfn-init拉取新配置。

至于你之前改LaunchTemplate名触发全量回滚,本质是替换整个LaunchTemplate和ASG的时候,新实例的cfn-signal没正常返回给CloudFormation——要么是UserData里的命令执行报错,要么是nginx、Nitro Enclave服务启动失败返回了非0状态码,你又配了100%实例成功才算完成,单台启动失败自然就触发回滚了。可以先在测试环境把cfn-init、cfn-signal的日志开全,排查下实例启动阶段的报错即可。

2. 替代方案

如果不想靠ASG自带的滚动更新策略替换实例,也可以选几个更可控的方案:

  • 直接用ASG自带的实例刷新功能,配好最小健康实例占比、分批大小,等LaunchTemplate新版本创建完后,手动或者靠EventBridge事件触发自动刷新,按批次替换旧实例。
  • 写简单的Lambda函数配合CloudFormation自定义资源,每次栈更新完自动调用ASG的实例刷新API,不用改ASG的UpdatePolicy配置,更新逻辑更灵活。
  • 如果对更新时效要求不高,不用特意做替换操作,配好ASG的实例终止策略,等实例运行到设定时长、或者后续扩缩容的时候,新启动的实例自然会用最新的LaunchTemplate版本,旧实例会被逐步淘汰。

3. 机制说明

你之前对LaunchTemplate的更新机制理解有偏差:CloudFormation托管AWS::EC2::LaunchTemplate时,所有对LaunchTemplateData的修改都会自动创建新版本,!GetAtt ec2LaunchTemplate.LatestVersionNumber会自动返回最新的版本号,不需要单独维护版本资源。
整套更新的逻辑可以按这几个核心规则梳理,不用找零散的命令文档:

  • LaunchTemplate修改完新版本,ASG不会自动替换存量实例,必须显式配置滚动更新策略、或者手动触发实例刷新,新启动的实例才会用新版本的配置。
  • UserData脚本只会在实例首次启动的时候执行一次,运行中的实例不会重新跑UserData。要给运行中的实例推配置变更,要么替换实例,要么靠cfn-hup触发cfn-init拉取最新的元数据配置。
  • 配置滚动更新的时候,PauseTime一定要留够,要覆盖实例启动、服务初始化、发送成功信号的全流程时长,不然CloudFormation等超时就会判定更新失败,直接触发回滚。

内容的提问来源于stack exchange,提问作者mark

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 19:06:32