AWS CloudFormation资源删除顺序异常及SizeConstraintSet删除失败问题
问题1:为何WafRule优先删除,如何确保WAFSizeCondition1在WafRule之后删除?
首先得纠正一个逻辑误区:依赖资源的删除顺序本就应该是“先删引用方,再删被引用方”。你的WafRule是引用WAFSizeCondition1的资源,所以正常删除流程就是先删WafRule,再删WAFSizeCondition1——这是符合依赖逻辑的,因为如果先删WAFSizeCondition1,WafRule会因为依赖缺失而删除失败。
那为什么你会对这个顺序产生疑问?可能是混淆了创建和删除的顺序:创建时是先建被引用的WAFSizeCondition1,再建引用它的WafRule;删除时顺序完全反转,这是CloudFormation的默认行为。
不过如果CloudFormation没有自动识别到WafRule对WAFSizeCondition1的依赖(因为是自定义资源的内部属性引用,CloudFormation对这类引用的依赖识别可能不够敏感),你可以通过显式添加DependsOn属性来强制声明依赖关系,确保删除顺序绝对正确:
修改WafRule资源的定义,添加DependsOn:
WafRule: Type: 'Custom::CustomResource' DependsOn: WAFSizeCondition1 # 显式声明依赖,确保删除顺序 Properties: ServiceToken: !Join - '' - - 'arn:aws:lambda:' - !Ref 'AWS::Region' - ':' - !Ref 'AWS::AccountId' - ':function:WafLambdaTest' Name: WAFRateTest1 RateLimit: '2000' MetricName: WAFRateTest1 Predicates: - DataId: !Ref WAFSizeCondition1 Negated: false Type: SizeConstraint
这样CloudFormation就会明确知道WafRule依赖WAFSizeCondition1,删除时一定会先处理WafRule,再处理WAFSizeCondition1。
问题2:为何WAFSizeCondition1无法删除,如何处理删除流程?
WAFSizeCondition1删除失败提示“被引用”,核心原因是你的自定义资源Lambda函数没有正确处理DELETE事件:
CloudFormation中的Custom::CustomResource只是一个“代理”,实际的WAF规则(WAFRateTest1)是由WafLambdaTest Lambda函数创建的。当CloudFormation发送DELETE事件给Lambda时,如果Lambda没有主动删除这个实际的WAF规则,那么这个规则会留在你的AWS账户中,依然引用着WAFSizeCondition1——这就导致CloudFormation尝试删除WAFSizeCondition1时,因为它还被真实存在的WAF规则引用而失败。
解决步骤:
手动清理遗留资源:
登录AWS WAF控制台,找到名为WAFRateTest1的规则,检查它的Predicates列表,确认是否还引用着你的WAFSizeCondition1。如果存在,直接删除这个规则,然后再尝试删除CloudFormation堆栈,此时WAFSizeCondition1应该能正常删除。修复Lambda函数的删除逻辑:
你需要修改WafLambdaTestLambda函数,确保它在收到DELETE事件时:- 根据事件中的资源属性(比如
Name或MetricName)找到对应的WAF规则 - 移除该规则对
WAFSizeCondition1的引用,或者直接删除整个规则 - 向CloudFormation发送成功的响应(必须包含
PhysicalResourceId和Status: SUCCESS),告知自定义资源已被正确清理
- 根据事件中的资源属性(比如
规范自定义资源的生命周期管理:
后续使用自定义资源时,一定要确保Lambda函数完整实现Create/Update/Delete三个生命周期事件的处理逻辑,否则很容易出现资源残留、依赖引用无法解除的问题。
内容的提问来源于stack exchange,提问作者Rudzianko怒

