Skip to content

Commit

Permalink
fix(assertions): nested stacks inside non-root stages don't resolve t…
Browse files Browse the repository at this point in the history
…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.

I took the opportunity to reduce the scope of synth to only the containing template, regardless of the stack being nested or not. This should decrease load on user machines when synthesizing templates for apps with multiple stages.

Closes #24004.
  • Loading branch information
Styerp committed Feb 4, 2023
1 parent 2b6a0be commit 4e75b00
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 4 deletions.
7 changes: 4 additions & 3 deletions packages/@aws-cdk/assertions/lib/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,12 +296,13 @@ export interface TemplateParsingOptions {
}

function toTemplate(stack: Stack): any {
const root = stack.node.root;
if (!Stage.isStage(root)) {
// get the nearest stage to the stack in the construct tree
const containingStage = stack.node.scopes.reverse().find(Stage.isStage);
if (!containingStage) {
throw new Error('unexpected: all stacks must be part of a Stage or an App');
}

const assembly = root.synth();
const assembly = containingStage.synth();
if (stack.nestedStackParent) {
// if this is a nested stack (it has a parent), then just read the template as a string
return JSON.parse(fs.readFileSync(path.join(assembly.directory, stack.templateFile)).toString('utf-8'));
Expand Down
25 changes: 24 additions & 1 deletion packages/@aws-cdk/assertions/test/template.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { App, CfnCondition, CfnMapping, CfnOutput, CfnParameter, CfnResource, Fn, LegacyStackSynthesizer, NestedStack, Stack } from '@aws-cdk/core';
import { App, CfnCondition, CfnMapping, CfnOutput, CfnParameter, CfnResource, Fn, LegacyStackSynthesizer, NestedStack, Stack, Stage } from '@aws-cdk/core';
import { Construct } from 'constructs';
import { Capture, Match, Template } from '../lib';

Expand Down Expand Up @@ -74,6 +74,29 @@ describe('Template', () => {
},
});
});

test('nested stack inside a Stage in an App', () => {
const app = new App();
const stage = new Stage(app, 'Stage');
const stack = new Stack(stage);
const nested = new NestedStack(stack, 'MyNestedStack');
new CfnResource(nested, 'Bar', {
type: 'Bar::Baz',
properties: {
Qux: 'Foo',
},
});
const template = Template.fromStack(nested);

expect(template.toJSON()).toEqual({
Resources: {
Bar: {
Type: 'Bar::Baz',
Properties: { Qux: 'Foo' },
},
},
});
});
});

describe('fromString', () => {
Expand Down

0 comments on commit 4e75b00

Please sign in to comment.