How to parametrize our AWS CDK stacks?
3 min read, last updated on 2020-12-22
In the previous blog post, we have talked about Constructs, which are the novel concept introduced specifically by CDK. However, this is not the last thing that requires a revolutionary approach to CDK.
If you have worked with CloudFormation, you are perfectly aware of how to parametrize the templates. That’s why you have a Parameters section (sometimes used with combination together with Mappings). But, that is not a recommended way to do it.
Parameters, but not Parameters
We need to ditch the CloudFormation parameters. Even the official documentation states:
In general, we recommend against using AWS CloudFormation parameters with the AWS CDK. Parameter values are not available at synthesis time and cannot be easily used in other parts of your AWS CDK App, particularly for control flow.
Fragment of the official AWS CDK documentation.
Due to their nature, we should use them only if you have to. A great example is when you have an existing CloudFormation template, and it will be much easier to import it to AWS CDK without reimplementation. And if you have to use them, you are working with those in precisely the same way as you got used to.
You can also explicitly read that it’s a low-level construct deliberately (a part of constructs from the lowest level, CFN Resources), because of guarantees that the CDK tool wants to provide. Because of a different evaluation approach, those parameters introduce a loophole that does not allow for verification during compilation.
How to do it then?
Well, we have at least two options available.
Solution 1: Use props and environment variables
This is probably your first guess. And I have to admit a good approximation.
It is a possible and working solution. You came up with this approach, probably because each CDK App is a typical application to pass environment variables during deployment/synthesis. Additionally, props can have types, so we will have our guarantees.
Solution 2: Use context and obtain those values in the runtime
Here comes the official way.
AWS CDK supports several context methods that enable apps to get contextual information. So unless we have good reasons (if you know any, let me know in the comments - I’m honestly interested), we should employ this approach.
Context is king?
Context values are made available to your AWS CDK app in six different ways:
- Automatically from the current AWS account. Do you remember what we have discussed in the article about bootstrap? That is an additional use case of those metadata.
- Through the -context option passed to the cdk command.
- In the project’s cdk.context.json file.
- In the context key of the project’s cdk.json file.
- In the context key of your ~/cdk.json file.
- In your AWS CDK App using the construct.node.setContext method.
The flexibility of this approach is definitely a win. Additionally, you can access context inside and from all possible levels by using construct.node.getContext method, like presented below (here is the repository with full example):
// Inside Participant construct:
const participant = new iam.User(
this,
`WorkshopUser${props.zeroPadded}`,
{
userName: `user${props.zeroPadded}`,
password:
cdk.SecretValue.plainText(
this.node.tryGetContext('initialPassword')
),
passwordResetRequired: true,
groups: [
props.commonGroup
]
}
);
Additionally, you can review the current state of the context with the following commands:
$ cdk context
$ cdk context -j # To view it as a JSON.
Summary
Thankfully that is the last place that requires a significant mind-shift compared to the old school methods with pure CloudFormation.
In the next article, we will discuss another important topic, how to share resources between the stacks. Stay tuned for more!