What is Context and its Significance in AWS CDK
Tags: aws, awscdk, iac, context
Published: 2023-12-15 15:44:29

---
title: What is Context and its Significance in AWS CDK
published: true
date: 2023-12-15 15:29:47 UTC
tags: #aws #awscdk #iac #context
canonical_url: https://blog.mikaeels.com/what-is-context-and-its-significance-in-aws-cdk
---

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jy43kughpfcl2uk5stji.jpeg)

Amazon Web Services Cloud Development Kit (AWS CDK) is a powerful infrastructure-as-code (IaC) framework that allows developers to define cloud infrastructure using familiar programming languages. One essential concept within AWS CDK that plays a crucial role in configuring and customizing your infrastructure is "context." In this blog post, we will delve into the significance of context in AWS CDK and how it contributes to the flexibility and scalability of your cloud applications.

### **Context in AWS CDK**

In AWS CDK, context refers to the external input provided during the synthesis phase of your application. This external input can be environmental variables, resource-specific configurations, or any changing parameter based on the deployment environment. Context allows you to dynamically adjust certain values in your CDK application without modifying the source code.

### Using Context at the App Level

In this example we will **set the context at our CDK App level** :

```
import { Stack, StackProps, App } from 'aws-cdk-lib';export class MyCdkStack extends Stack { constructor(scope: App, id: string, props?: StackProps) { super(scope, id, props); console.log('accessing context here ', this.node.tryGetContext('fromApp')); }}const app = new App({ // setting context in our cdk.App context: { fromApp: {name: 'Mikaeel', country: 'BE'}, },});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:

```
cdk synth
```

We can see the output from the `console.log`:

```
{ name: 'Mikaeel', country: 'BE' }
```

### Context Managed by CDK

Now 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 { Stack, StackProps, App } from 'aws-cdk-lib';export class MyCdkStack extends Stack { constructor(scope: App, id: string, props?: StackProps) { super(scope, id, props); console.log('context passed in App here ', this.node.tryGetContext('fromApp')); // printing the availability zones console.log(Stack.of(this).availabilityZones); }}
```

Now synthesize our stack with:

```
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:

```
{ "availability-zones:account=123456789:region=us-east-1": ["us-east-1a", "us-east-1b", "us-east-1c", "us-east-1d", "us-east-1e"]}
```

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 bin/aws-cdk-group-chat-app.ts", "context": { "@aws-cdk/aws-lambda:recognizeLayerVersion": true, "@aws-cdk/core:checkSecretUsage": true, "@aws-cdk/core:target-partitions": ["aws", "aws-cn"] }}
```

Where the `app` key indicates to the CDK CLI how to run our CDK code, which is mostly 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-lambda`.

💡

**If we want to roll back to the previous behavior of AWS CDK what certain feature is concerned, we have to set the feature flag to** `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 bin/aws-cdk-group-chat-app.ts", "context": { "@aws-cdk/aws-lambda:recognizeLayerVersion": true, "@aws-cdk/core:checkSecretUsage": true, "@aws-cdk/core:target-partitions": ["aws", "aws-cn"], // adding a bucket property as context "bucket": { "region": "us-east-1", "name": "my-s3-bucket" } }}
```

Now let's access the bucket context in our CDK stack:

```
import { Stack, StackProps, App } from 'aws-cdk-lib';export class MyCdkStack extends Stack { constructor(scope: App, id: string, props?: StackProps) { super(scope, id, props); console.log('from cdk.json ', this.node.tryGetContext('bucket')); }}
```

Let's synth our cdk stack:

```
cdk synth
```

The output from the `console.log` will look like this:

```
 { "region": "us-east-1", "name": "my-s3-bucket" }
```

### Setting Context using the CDK CLI

The next option used for setting context in our CDK app is to use the [**CDK CLI**](https://docs.aws.amazon.com/cdk/v2/guide/cli.html).

We can set context key-value pairs during synthesis.

First, we'll access context values that we haven't yet set:

```
import { Stack, StackProps, App } from 'aws-cdk-lib';export class MyCdkStack extends Stack { constructor(scope: App, id: string, props?: StackProps) { super(scope, id, props); console.log('bucketName ', this.node.tryGetContext('bucketName')); console.log('region ', this.node.tryGetContext('region')); }}
```

Now we'll synth the CDK application passing in the context values using the CLI:

```
cdk synth \ --context bucketName=myBucket \ --context region=us-east-1
```

The output from our `console.log` statements will look like this.

```
bucketName myBucketregion us-east-1
```

💡

**We can only pass** `string` **values when we set the 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.:

```
cdk synth \ --context stack-name1:bucketName=myBucket \ --context stack-name2:bucketName=yourBucket
```

### Conclusion

**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:

- At the CDK App level using the `context` property

- In our `cdk.json` file adding key-value pairs to the `context` object

- Using the CDK CLI with the `--context` flag

In our CDK applications, we can access the context values with a call to`this.node.tryGetContext('keyName')`.

💡

**I believe it's good to set the context at the** `CDK App level` **, it's globally available, it's intuitive and we can set context values of any type.**

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.