如何将自定义CloudFormation资源替换为官方AWS::Shield::Protection资源
批量替换CloudFormation自定义Shield防护资源为官方资源的可行方案
针对数千个自动化生成的CloudFormation堆栈,要避免直接替换时的创建冲突,结合你可修改自定义资源实现、生成模板时可调用AWS API的条件,提供以下三个可落地的方案:
方案一:分阶段迭代+资源导入(推荐)
第一阶段:更新自定义资源,实现防护移交准备
- 修改自定义资源的Lambda处理逻辑:
- 当接收到
Delete事件时,不删除底层的Shield Protection,而是给该防护添加专属标签(如CFN_Migration=Completed),同时返回防护的ARN作为输出参数。 - 保留原有
Create/Update逻辑,确保防护正常运行。
- 当接收到
- 生成模板时,保留原有自定义资源定义,新增一个输出项暴露防护ARN。
- 批量执行堆栈更新:这一步仅更新自定义资源的逻辑,不会改变物理防护状态。
第二阶段:替换为官方资源并导入现有防护
- 生成新模板时,先调用
DescribeProtectionsAPI,通过关联的受保护资源ARN或第一阶段添加的标签,查询到对应Shield防护的ARN。 - 删除模板中的自定义资源,添加官方
AWS::Shield::Protection资源:- 设置
DeletionPolicy: Retain,防止误删现有防护。 - 在
Properties中指定正确的ResourceArn(即受保护的目标资源ARN),确保与现有防护的配置一致。
- 设置
- 批量执行堆栈更新+资源导入:使用CloudFormation的资源导入功能,将已存在的Shield防护直接关联到新的官方资源上。部署平台可自动生成
aws cloudformation import-resources命令,或在更新时通过--import-resources参数完成关联,避免创建新防护的冲突。
方案二:自定义资源兼容官方资源的共存过渡
- 修改自定义资源的Lambda逻辑:
- 在
Create/Update事件中,先调用DescribeProtectionsAPI检测目标资源是否已存在Shield防护。 - 若已存在,跳过防护创建流程,仅同步标签、描述等属性;若不存在,正常创建防护。
- 在
- 生成模板时,同时保留自定义资源和官方
AWS::Shield::Protection资源:- 给官方资源添加
Condition,仅当API查询到现有防护不属于自定义资源管理时才创建(可通过标签或创建者ID判断)。 - 给官方资源设置
DependsOn: CustomShieldProtection,确保自定义资源先完成清理逻辑。
- 给官方资源添加
- 批量执行一次堆栈更新:自定义资源会自动放弃对现有防护的管理,官方资源直接接管,后续可逐步移除自定义资源。
方案三:参数触发的自定义资源主动移交
- 修改自定义资源的Lambda逻辑:
- 新增对模板参数
MigrateToOfficial的检测,当参数值为true时,在Update事件中主动触发“移交”逻辑:给现有防护打标签,同时在内部标记该资源已不再受自定义资源管理。 - 当接收到
Delete事件时,直接返回成功,不删除物理防护。
- 新增对模板参数
- 生成模板时:
- 第一次更新:保留自定义资源,添加
MigrateToOfficial=true的参数,执行批量更新,此时所有自定义资源会完成移交标记。 - 第二次更新:删除自定义资源,添加官方
AWS::Shield::Protection资源,设置DeletionPolicy: Retain并指定正确的ResourceArn,批量执行更新即可完成替换。
- 第一次更新:保留自定义资源,添加
关键注意事项
- 所有方案中,必须确保自定义资源的
Delete逻辑不会删除物理防护,避免防护中断。 - 调用AWS API时,需通过资源ARN、标签等唯一标识过滤,避免关联错误的Shield防护。
- 官方资源的配置需与现有防护完全一致(如资源ARN、名称),否则导入或更新会失败。
内容的提问来源于stack exchange,提问作者Tommy Brunn
相关产品推荐
相关产品推荐

