Skip to content

Commit 2d4a60d

Browse files
authored
fix(assertions): nested stacks inside non-root stages don't resolve t… (#25006)
…emplates Templates are placed inside a path described by their closest assembly. Using this assembly lets nested stack templates resolve, regardless of their stage depth. Previously, they would fail to resolve if they were in a stage other than the app. Closes #24004. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 8ca4c09 commit 2d4a60d

File tree

2 files changed

+39
-4
lines changed

2 files changed

+39
-4
lines changed

packages/aws-cdk-lib/assertions/lib/template.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -296,12 +296,12 @@ export interface TemplateParsingOptions {
296296
}
297297

298298
function toTemplate(stack: Stack): any {
299-
const root = stack.node.root;
300-
if (!Stage.isStage(root)) {
299+
const stage = Stage.of(stack);
300+
if (!Stage.isStage(stage)) {
301301
throw new Error('unexpected: all stacks must be part of a Stage or an App');
302302
}
303303

304-
const assembly = root.synth();
304+
const assembly = stage.synth();
305305
if (stack.nestedStackParent) {
306306
// if this is a nested stack (it has a parent), then just read the template as a string
307307
return JSON.parse(fs.readFileSync(path.join(assembly.directory, stack.templateFile)).toString('utf-8'));

packages/aws-cdk-lib/assertions/test/template.test.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
1-
import { App, CfnCondition, CfnMapping, CfnOutput, CfnParameter, CfnResource, Fn, LegacyStackSynthesizer, NestedStack, Stack } from '../../core';
1+
import {
2+
App,
3+
CfnCondition,
4+
CfnMapping,
5+
CfnOutput,
6+
CfnParameter,
7+
CfnResource,
8+
Fn,
9+
LegacyStackSynthesizer,
10+
NestedStack,
11+
Stack,
12+
Stage
13+
} from '../../core';
214
import { Construct } from 'constructs';
315
import { Capture, Match, Template } from '../lib';
416

@@ -1353,6 +1365,29 @@ describe('Template', () => {
13531365
});
13541366
}).not.toThrow(/dependency cycle/);
13551367
});
1368+
1369+
test('nested stack inside a Stage in an App', () => {
1370+
const app = new App();
1371+
const stage = new Stage(app, 'Stage');
1372+
const stack = new Stack(stage);
1373+
const nested = new NestedStack(stack, 'MyNestedStack');
1374+
new CfnResource(nested, 'Bar', {
1375+
type: 'Bar::Baz',
1376+
properties: {
1377+
Qux: 'Foo',
1378+
},
1379+
});
1380+
const template = Template.fromStack(nested);
1381+
1382+
expect(template.toJSON()).toEqual({
1383+
Resources: {
1384+
Bar: {
1385+
Type: 'Bar::Baz',
1386+
Properties: { Qux: 'Foo' },
1387+
},
1388+
},
1389+
});
1390+
});
13561391
});
13571392

13581393
function expectToThrow(fn: () => void, msgs: (RegExp | string)[]): void {

0 commit comments

Comments
 (0)