Describe the bug
ResourceDifference.changeImpact classifies a resource removal as WILL_ORPHAN only when DeletionPolicy is exactly 'Retain'; every other value falls through to WILL_DESTROY:
https://github.com/aws/aws-cdk-cli/blob/main/packages/%40aws-cdk/cloudformation-diff/lib/diff/types.ts#L725-L727
if (this.resourceTypes.newType === undefined) {
return this.oldValue!.DeletionPolicy === 'Retain'
? ResourceImpact.WILL_ORPHAN
: ResourceImpact.WILL_DESTROY;
}
The strings RetainExceptOnCreate and Snapshot do not appear anywhere else in the package, so there is no compensating handling.
Two distinct problems:
-
RetainExceptOnCreate → WILL_DESTROY is incorrect. For any resource that was successfully created, RetainExceptOnCreate behaves identically to Retain on stack update and delete — the physical resource is retained (DeletionPolicy attribute documentation). Since a resource being removed from an existing stack was by definition created previously, WILL_ORPHAN is the correct impact in effectively all cases this code path evaluates.
-
Snapshot → WILL_DESTROY is misleading and undocumented. The physical resource is deleted, but CloudFormation takes a final snapshot first, so the data is recoverable. That may be intentionally conservative for display purposes, but downstream consumers of changeImpact currently cannot distinguish "data destroyed" from "data recoverable from a snapshot." A dedicated impact (e.g. WILL_SNAPSHOT) would fix that; failing that, documenting on ResourceImpact.WILL_DESTROY that it also covers snapshot-protected deletions would at least make the behavior intentional.
Current Behavior
Observed impacts for a removed AWS::RDS::DBInstance by DeletionPolicy value (@aws-cdk/cloudformation-diff@2.187.3):
| DeletionPolicy |
changeImpact |
Correct? |
Delete |
WILL_DESTROY |
yes |
Retain |
WILL_ORPHAN |
yes |
RetainExceptOnCreate |
WILL_DESTROY |
no — resource is retained |
Snapshot |
WILL_DESTROY |
misleading — final snapshot is taken |
Reproduction Steps
const { fullDiff } = require('@aws-cdk/cloudformation-diff');
for (const policy of ['Delete', 'Retain', 'RetainExceptOnCreate', 'Snapshot']) {
const before = { Resources: { Db: { Type: 'AWS::RDS::DBInstance', DeletionPolicy: policy } } };
const after = { Resources: {} };
console.log(String(policy).padEnd(22), '->', fullDiff(before, after).resources.get('Db').changeImpact);
}
Output:
Delete -> WILL_DESTROY
Retain -> WILL_ORPHAN
RetainExceptOnCreate -> WILL_DESTROY
Snapshot -> WILL_DESTROY
Expected Behavior
RetainExceptOnCreate → WILL_ORPHAN
Snapshot → a dedicated impact, or explicit documentation that WILL_DESTROY includes snapshot-protected deletions
Possible Solution
For the clear-cut part:
return this.oldValue!.DeletionPolicy === 'Retain' || this.oldValue!.DeletionPolicy === 'RetainExceptOnCreate'
? ResourceImpact.WILL_ORPHAN
: ResourceImpact.WILL_DESTROY;
Adding a WILL_SNAPSHOT member to ResourceImpact would address the second part, with the caveat that consumers switching exhaustively on the enum would see a new case. The === 'Retain' comparison occurs only at this one site in the package, so the fix is contained.
Environment
@aws-cdk/cloudformation-diff: 2.187.3 (also present on current main, permalink above)
- Node.js: v24.18.0
- OS: macOS 26.6.1
I'm happy to open a PR for the RetainExceptOnCreate fix referencing this issue, leaving the WILL_SNAPSHOT question to maintainers as an API decision.
Describe the bug
ResourceDifference.changeImpactclassifies a resource removal asWILL_ORPHANonly whenDeletionPolicyis exactly'Retain'; every other value falls through toWILL_DESTROY:https://github.com/aws/aws-cdk-cli/blob/main/packages/%40aws-cdk/cloudformation-diff/lib/diff/types.ts#L725-L727
The strings
RetainExceptOnCreateandSnapshotdo not appear anywhere else in the package, so there is no compensating handling.Two distinct problems:
RetainExceptOnCreate→WILL_DESTROYis incorrect. For any resource that was successfully created,RetainExceptOnCreatebehaves identically toRetainon stack update and delete — the physical resource is retained (DeletionPolicy attribute documentation). Since a resource being removed from an existing stack was by definition created previously,WILL_ORPHANis the correct impact in effectively all cases this code path evaluates.Snapshot→WILL_DESTROYis misleading and undocumented. The physical resource is deleted, but CloudFormation takes a final snapshot first, so the data is recoverable. That may be intentionally conservative for display purposes, but downstream consumers ofchangeImpactcurrently cannot distinguish "data destroyed" from "data recoverable from a snapshot." A dedicated impact (e.g.WILL_SNAPSHOT) would fix that; failing that, documenting onResourceImpact.WILL_DESTROYthat it also covers snapshot-protected deletions would at least make the behavior intentional.Current Behavior
Observed impacts for a removed
AWS::RDS::DBInstancebyDeletionPolicyvalue (@aws-cdk/cloudformation-diff@2.187.3):DeleteWILL_DESTROYRetainWILL_ORPHANRetainExceptOnCreateWILL_DESTROYSnapshotWILL_DESTROYReproduction Steps
Output:
Expected Behavior
RetainExceptOnCreate→WILL_ORPHANSnapshot→ a dedicated impact, or explicit documentation thatWILL_DESTROYincludes snapshot-protected deletionsPossible Solution
For the clear-cut part:
Adding a
WILL_SNAPSHOTmember toResourceImpactwould address the second part, with the caveat that consumers switching exhaustively on the enum would see a new case. The=== 'Retain'comparison occurs only at this one site in the package, so the fix is contained.Environment
@aws-cdk/cloudformation-diff: 2.187.3 (also present on currentmain, permalink above)I'm happy to open a PR for the
RetainExceptOnCreatefix referencing this issue, leaving theWILL_SNAPSHOTquestion to maintainers as an API decision.