CDK documentation states that if you supply stack name(s) to CLI commands like cdk synth
, cdk list
, or cdk deploy
– it will synthesize only the stacks you requested. But in reality this is not the case, CDK will always synthesize all stacks – and it may lead to unintended consequences.
Let’s say you have following stack declarations in your lib/my-stacks.ts
code:
import * as cdk from 'aws-cdk-lib'; export class Stack1 extends cdk.Stack {}; export class Stack2 extends cdk.Stack {}; export class AnotherStack extends cdk.Stack {}; export class YerAnotherStack extends cdk.Stack {};
And in your app’s entry point bin/my-stacks.ts
you instantiate those stacks:
import * as cdk from 'aws-cdk-lib'; import * as stacks from '../lib/my-stacks' const app = new cdk.App(); new stacks.Stack1(app, "Stack1"); new stacks.Stack2(app, "Stack2"); new stacks.AnotherStack(app, "AnotherStack"); new stacks.YerAnotherStack(app, "YetAnotherStack");
And then issue a CLI command to synthesize stacks, but you only want to synthesize “Stack1” and “AnotherStack”:
cdk synth Stack1 AnotherStack
The command output would have you believe that only 2 stacks were synthesized:
Successfully synthesized to ./cdk.out Supply a stack id (AnotherStack, Stack1) to display its template.
But if you actually look into cdk.out folder – you will see all stack templates were synthesized:
AnotherStack.assets.json Stack2.assets.json AnotherStack.template.json Stack2.template.json Stack1.assets.json YetAnotherStack.assets.json Stack1.template.json YetAnotherStack.template.json
CDK will synthesize templates for all stacks you instantiate no matter what stack names you pass – the names will only be used to filter the results. In order to synthesize only the stacks you request – only classes for the stacks you request must be instantiated. We can pass the stack names to a CDK command using context via option --context
or its shorter form -c
:
cdk synth -c stacks=Stack1,AnotherStack
And this is how we can interpret this in our entry point code:
import * as cdk from 'aws-cdk-lib'; import * as stacks from '../lib/my-stacks' const app = new cdk.App(); const myStacks: string = app.node.tryGetContext('stacks'); Object.entries(stacks).forEach(([stackName, stack]) => { if (!myStacks || myStacks.split(',').includes(stackName)) { new stack(app, stackName) } })
Here on Line 05 we read the context parameter we passed in the command line. And on Lines 07-11 we loop thru imported stacks. If stack name matches one of the names we passed as a parameter – only then it will be instantiated. If the -c stacks
parameter isn’t passed – the value will be undefined – and all stacks will be instantiated and therefore synthesized.
Now, if you issue the command (don’t forget to clear previous content of cdk.out
):
cdk synth -c stacks=Stack1,AnotherStack
The output will be the same as before:
Successfully synthesized to ./cdk.out Supply a stack id (AnotherStack, Stack1) to display its template.
But if you look into cdk.out directory – you will only see requested stacks synthesized:
]AnotherStack.assets.json AnotherStack.template.json Stack1.assets.json Stack1.template.json