Skip to content

Commit 4f3a340

Browse files
authored
fix(cfn-diff): allow resources to change types (#19891)
When writing the cloudformation-diff module, it was assumed that resources would never change their CloudFormation types between deployments. As it turns out, there is a legitimate case for resources changing types, and that's when you migrate from a template that uses Transforms (like the Serverless Transform) to one that doesn't use them. Because of that, handle the case of resources changing types in diff. Fixes #13921 ---- ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/master/CONTRIBUTING.md) ### Adding new Unconventional Dependencies: * [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/master/CONTRIBUTING.md/#adding-new-unconventional-dependencies) ### New Features * [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/master/INTEGRATION_TESTS.md)? * [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent c421a5f commit 4f3a340

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

packages/@aws-cdk/cloudformation-diff/lib/diff/types.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,10 @@ export class TemplateDiff implements ITemplateDiff {
114114
const ret = new Array<PropertyChange>();
115115

116116
for (const [resourceLogicalId, resourceChange] of Object.entries(this.resources.changes)) {
117-
if (!resourceChange) { continue; }
117+
if (resourceChange.resourceTypeChanged) {
118+
// we ignore resource type changes here, and handle them in scrutinizableResourceChanges()
119+
continue;
120+
}
118121

119122
const props = cfnspec.scrutinizablePropertyNames(resourceChange.newResourceType!, scrutinyTypes);
120123
for (const propertyName of props) {
@@ -152,7 +155,7 @@ export class TemplateDiff implements ITemplateDiff {
152155
resourceLogicalId,
153156
};
154157

155-
// Even though it's not physically possible in CFN, let's pretend to handle a change of 'Type'.
158+
// changes to the Type of resources can happen when migrating from CFN templates that use Transforms
156159
if (resourceChange.resourceTypeChanged) {
157160
// Treat as DELETE+ADD
158161
if (scrutinizableTypes.has(resourceChange.oldResourceType!)) {

packages/@aws-cdk/cloudformation-diff/test/diff-template.test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,3 +655,37 @@ test('when a property with a number-like format doesn\'t change', () => {
655655
const difference = differences.resources.changes.BucketResource;
656656
expect(difference).toBeUndefined();
657657
});
658+
659+
test('handles a resource changing its Type', () => {
660+
const currentTemplate = {
661+
Resources: {
662+
FunctionApi: {
663+
Type: 'AWS::Serverless::Api',
664+
Properties: {
665+
StageName: 'prod',
666+
},
667+
},
668+
},
669+
};
670+
const newTemplate = {
671+
Resources: {
672+
FunctionApi: {
673+
Type: 'AWS::ApiGateway::RestApi',
674+
},
675+
},
676+
};
677+
678+
const differences = diffTemplate(currentTemplate, newTemplate);
679+
expect(differences.differenceCount).toBe(1);
680+
expect(differences.resources.differenceCount).toBe(1);
681+
const difference = differences.resources.changes.FunctionApi;
682+
expect(difference).toEqual({
683+
isAddition: false,
684+
isRemoval: false,
685+
newValue: { Type: 'AWS::ApiGateway::RestApi' },
686+
oldValue: { Properties: { StageName: 'prod' }, Type: 'AWS::Serverless::Api' },
687+
otherDiffs: {},
688+
propertyDiffs: {},
689+
resourceTypes: { newType: 'AWS::ApiGateway::RestApi', oldType: 'AWS::Serverless::Api' },
690+
});
691+
});

0 commit comments

Comments
 (0)