Last updated: Jan 27, 2024
Reading timeยท5 min
Context in CDK is a combination of key-value pairs we can set in our CDK application.
These key-value pairs are going to be available at synthesis time, which means that we can use them in our code, i.e. in conditional statements.
The CDK library uses context to:
feature flags
. Feature flags provide a way to opt in or out of
new functionality that introduces breaking changes, outside of a major CDK
version release.We use context to set key-value pairs we can then access in our CDK code, in a similar way to environment variables.
We are going to create a simple CDK application to demo using context.
First, let's look at an example where we set the context at our CDK App level.
import * as cdk from 'aws-cdk-lib'; export class MyCdkStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); console.log('accessing context ๐', this.node.tryGetContext('fromApp')); } } const app = new cdk.App({ // ๐ setting context in our cdk.App context: { fromApp: {name: 'John', age: 28}, }, }); const myStack = new MyCdkStack(app, 'my-cdk-stack', { stackName: `my-cdk-stack`, env: { region: process.env.CDK_DEFAULT_REGION, account: process.env.CDK_DEFAULT_ACCOUNT, }, });
Let's synthesize our stack and look at the output.
npx aws-cdk synth
We can see the output from the console.log
call we made in our CDK stack.
Let's take a quick look at how CDK uses context to cache certain values that belong to our deployment environment.
If we open the cdk.context.json
file in the root directory of our CDK project,
we can see that it's empty.
{}
Let's add a simple console.log
call and print the availability zones that
belong to the region our stack is configured for:
import * as cdk from 'aws-cdk-lib'; export class MyCdkStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); console.log('context passed in App ๐', this.node.tryGetContext('fromApp')); // ๐ printing the availabilityZones console.log(cdk.Stack.of(this).availabilityZones); } }
Now, let's synthesize our stack with the synth
command.
npx aws-cdk synth
If we now open the cdk.context.json
file in the root of our project we'll see
that CDK has cached the availability zones that correspond to our stack's
region. In my case that's the eu-central-1
region.
{ "availability-zones:account=123456789:region=eu-central-1": [ "eu-central-1a", "eu-central-1b", "eu-central-1c" ] }
The cdk.context.json
file is where CDK caches values related to our deployment
environment.
There is also a cdk.json file in the root directory of a CDK project.
The cdk.json
file looks similar to the following:
{ "app": "npx ts-node --prefer-ts-exts infra/app.ts", "context": { "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": true, "@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": false, } }
Where the app
key indicates to the CDK CLI how to run our CDK code. In my case
it's a compilation step that compiles the typescript code to javascript.
Then we have the context
key, which is composed of feature flags.
These feature flags enable us to opt in or out of breaking changes. Their
names start with the name of the package that introduces the breaking change -
i.e. @aws-cdk/aws-kms
.
false
.We can also use the cdk.json
file to pass in context into our CDK app, let's
add another property to it:
{ "app": "npx ts-node --prefer-ts-exts infra/app.ts", "context": { // ๐ adding a bucket property "bucket": { "region": "us-east-1", "name": "my-bucket" } } }
Now let's access the bucket context in our CDK stack:
import * as cdk from 'aws-cdk-lib'; export class MyCdkStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); console.log('from cdk.json ๐', this.node.tryGetContext('bucket')); } }
Let's synth our CDK stack.
npx aws-cdk synth
The output from the console.log
call looks like:
The next option used for setting context in our CDK app is to use the CDK CLI.
We can set context key-value pairs during synthesis.
First, we'll access context values that we haven't yet set:
import * as cdk from 'aws-cdk-lib'; export class MyCdkStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); console.log('bucketName ๐', this.node.tryGetContext('bucketName')); console.log('region ๐', this.node.tryGetContext('region')); } }
And now we'll synth the CDK application passing in the context values using the CLI.
npx aws-cdk synth \ --context bucketName=myBucket \ --context region=us-east-1
The output from our console.log
statements looks as follows.
string
values when we set context using the CDK CLI. If we have to pass an object, we have to pass it as a string
and parse it in our application code.If we have multiple CDK stacks and want to set different context values using the CDK CLI, we can prefix the key-value pairs with the stack name, i.e.:
npx aws-cdk synth \ --context my-stack:bucketName=myBucket \ --context your-stack:bucketName=yourBucket
Context is a combination of key-value pairs we can set and make available in our CDK application.
Context is similar to environment variables, in that both are accessible in synthesis time, as opposed to CDK parameters, which are only set at deployment time.
The most common ways to set context are:
context
property.cdk.json
file adding key-value pairs to the context
object.--context
flag.In our CDK applications, we can access the context values with a call to
this.node.tryGetContext('keyName')
.
Setting context using the cdk.json
file is too implicit and hidden.
An alternative is using the CDK CLI, however, the CLI only allows us to pass in
string values, so the most intuitive way is setting context at the cdk.App
level.
You can learn more about the related topics by checking out the following tutorials: