Categories
AWS CDK

How to parametrize our AWS CDK stacks?

Because we use AWS CDK in some areas, we need to adjust our previous approach based, which is based on the experience. Parametrizing stacks is such a place, and today, we will address that difference.

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 when it comes to CDK.

If you have worked with CloudFormation, you are perfectly aware of the fact 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.

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 thus 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.

Also, you can 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, so we can 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:

  1. 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.
  2. Through the –context option passed to the cdk command.
  3. In the project’s cdk.context.json file.
  4. In the context key of the project’s cdk.json file.
  5. In the context key of your ~/cdk.json file.
  6. 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 what is the current state of the context, with following commands:

$ aws cdk context $ aws 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!

By Wojciech Gawroński

Principal Cloud Architect at Pattern Match. Infrastructure as Code, DevOps culture and AWS aficionado. Functional Programming wrangler (Erlang/Elixir).

Comments

This site uses Akismet to reduce spam. Learn how your comment data is processed.