Skip to content

Commit 466f170

Browse files
authored
fix(CLI): diff --template crashes (#29896)
### Issue # (if applicable) Closes #29890. ### Reason for this change `cdk diff` crashes with `--template`. ### Description of changes The addition of changeset logic had a leftover refactor that should not have been leftover (trying to pass a template directly instead of a stack artifact). Removes changeset creation code from fixed template mode, which should never create a changeset, and adds a unit test for fixed template diffs so we don't break this in the future. ### Description of how you validated changes unit tests + manual testing. CLI integ tests will be added in a follow-up PR. ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 7360a88 commit 466f170

File tree

2 files changed

+71
-33
lines changed

2 files changed

+71
-33
lines changed

packages/aws-cdk/lib/cdk-toolkit.ts

Lines changed: 2 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -136,41 +136,10 @@ export class CdkToolkit {
136136
throw new Error(`There is no file at ${options.templatePath}`);
137137
}
138138

139-
let changeSet = undefined;
140-
141-
if (options.changeSet) {
142-
let stackExists = false;
143-
try {
144-
stackExists = await this.props.deployments.stackExists({
145-
stack: stacks.firstStack,
146-
deployName: stacks.firstStack.stackName,
147-
tryLookupRole: true,
148-
});
149-
} catch (e: any) {
150-
debug(e.message);
151-
stream.write('Checking if the stack exists before creating the changeset has failed, will base the diff on template differences (run again with -v to see the reason)\n');
152-
stackExists = false;
153-
}
154-
155-
if (stackExists) {
156-
changeSet = await createDiffChangeSet({
157-
stack: stacks.firstStack,
158-
uuid: uuid.v4(),
159-
deployments: this.props.deployments,
160-
willExecute: false,
161-
sdkProvider: this.props.sdkProvider,
162-
parameters: Object.assign({}, parameterMap['*'], parameterMap[stacks.firstStack.stackName]),
163-
stream,
164-
});
165-
} else {
166-
debug(`the stack '${stacks.firstStack.stackName}' has not been deployed to CloudFormation or describeStacks call failed, skipping changeset creation.`);
167-
}
168-
}
169-
170139
const template = deserializeStructure(await fs.readFile(options.templatePath, { encoding: 'UTF-8' }));
171140
diffs = options.securityOnly
172-
? numberFromBool(printSecurityDiff(template, stacks.firstStack, RequireApproval.Broadening, changeSet))
173-
: printStackDiff(template, stacks.firstStack.template, strict, contextLines, quiet, changeSet, false, stream);
141+
? numberFromBool(printSecurityDiff(template, stacks.firstStack, RequireApproval.Broadening, undefined))
142+
: printStackDiff(template, stacks.firstStack, strict, contextLines, quiet, undefined, false, stream);
174143
} else {
175144
// Compare N stacks against deployed templates
176145
for (const stack of stacks.stackArtifacts) {

packages/aws-cdk/test/diff.test.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,75 @@ let cloudExecutable: MockCloudExecutable;
1414
let cloudFormation: jest.Mocked<Deployments>;
1515
let toolkit: CdkToolkit;
1616

17+
describe('fixed template', () => {
18+
const templatePath = 'oldTemplate.json';
19+
beforeEach(() => {
20+
const oldTemplate = {
21+
Resources: {
22+
SomeResource: {
23+
Type: 'AWS::SomeService::SomeResource',
24+
Properties: {
25+
Something: 'old-value',
26+
},
27+
},
28+
},
29+
};
30+
31+
cloudExecutable = new MockCloudExecutable({
32+
stacks: [{
33+
stackName: 'A',
34+
template: {
35+
Resources: {
36+
SomeResource: {
37+
Type: 'AWS::SomeService::SomeResource',
38+
Properties: {
39+
Something: 'new-value',
40+
},
41+
},
42+
},
43+
},
44+
}],
45+
});
46+
47+
toolkit = new CdkToolkit({
48+
cloudExecutable,
49+
deployments: cloudFormation,
50+
configuration: cloudExecutable.configuration,
51+
sdkProvider: cloudExecutable.sdkProvider,
52+
});
53+
54+
fs.writeFileSync(templatePath, JSON.stringify(oldTemplate));
55+
});
56+
57+
afterEach(() => fs.rmSync(templatePath));
58+
59+
test('fixed template with valid templates', async () => {
60+
// GIVEN
61+
const buffer = new StringWritable();
62+
63+
// WHEN
64+
const exitCode = await toolkit.diff({
65+
stackNames: ['A'],
66+
stream: buffer,
67+
changeSet: undefined,
68+
templatePath,
69+
});
70+
71+
// THEN
72+
const plainTextOutput = buffer.data.replace(/\x1B\[[0-?]*[ -/]*[@-~]/g, '');
73+
expect(exitCode).toBe(0);
74+
expect(plainTextOutput.replace(/\x1B\[[0-?]*[ -/]*[@-~]/g, '')).toContain(`Resources
75+
[~] AWS::SomeService::SomeResource SomeResource
76+
└─ [~] Something
77+
├─ [-] old-value
78+
└─ [+] new-value
79+
80+
81+
✨ Number of stacks with differences: 1
82+
`);
83+
});
84+
});
85+
1786
describe('imports', () => {
1887
beforeEach(() => {
1988
const outputToJson = {

0 commit comments

Comments
 (0)