diff --git a/packages/@aws-cdk/cloudformation-diff/lib/diff-template.ts b/packages/@aws-cdk/cloudformation-diff/lib/diff-template.ts index d84cc83a082d7..734753b1d7fc9 100644 --- a/packages/@aws-cdk/cloudformation-diff/lib/diff-template.ts +++ b/packages/@aws-cdk/cloudformation-diff/lib/diff-template.ts @@ -221,6 +221,10 @@ function addImportInformation(diff: types.TemplateDiff, changeSet: CloudFormatio function filterFalsePositivies(diff: types.TemplateDiff, changeSet: CloudFormation.DescribeChangeSetOutput) { const replacements = findResourceReplacements(changeSet); diff.resources.forEachDifference((logicalId: string, change: types.ResourceDifference) => { + if (change.resourceType.includes('AWS::Serverless')) { + // CFN applies the SAM transform before creating the changeset, so the changeset contains no information about SAM resources + return; + } change.forEachDifference((type: 'Property' | 'Other', name: string, value: types.Difference | types.PropertyDifference) => { if (type === 'Property') { if (!replacements[logicalId]) { diff --git a/packages/@aws-cdk/cloudformation-diff/test/diff-template.test.ts b/packages/@aws-cdk/cloudformation-diff/test/diff-template.test.ts index 805e8a9a7767e..4d97244803254 100644 --- a/packages/@aws-cdk/cloudformation-diff/test/diff-template.test.ts +++ b/packages/@aws-cdk/cloudformation-diff/test/diff-template.test.ts @@ -1118,6 +1118,55 @@ describe('changeset', () => { expect(differences.resources.differenceCount).toBe(1); }); + test('SAM Resources are rendered with changeset diffs', () => { + // GIVEN + const currentTemplate = { + Resources: { + ServerlessFunction: { + Type: 'AWS::Serverless::Function', + Properties: { + CodeUri: 's3://bermuda-triangle-1337-bucket/old-handler.zip', + }, + }, + }, + }; + + // WHEN + const newTemplate = { + Resources: { + ServerlessFunction: { + Type: 'AWS::Serverless::Function', + Properties: { + CodeUri: 's3://bermuda-triangle-1337-bucket/new-handler.zip', + }, + }, + }, + }; + + let differences = fullDiff(currentTemplate, newTemplate, { + Changes: [ + { + Type: 'Resource', + ResourceChange: { + Action: 'Modify', + LogicalResourceId: 'ServerlessFunction', + ResourceType: 'AWS::Lambda::Function', // The SAM transform is applied before the changeset is created, so the changeset has a Lambda resource here! + Replacement: 'False', + Details: [{ + Evaluation: 'Direct', + Target: { + Attribute: 'Properties', + Name: 'Code', + RequiresRecreation: 'Never', + }, + }], + }, + }, + ], + }); + expect(differences.resources.differenceCount).toBe(1); + }); + test('imports are respected for new stacks', async () => { // GIVEN const currentTemplate = {};