How to use Outputs in AWS CDK


Borislav Hadzhiev

Last updated: Apr 14, 2022


Check out my new book

Using Outputs in CDK #

Outputs are values that we can import into other stacks or simply redirect to a file on the local file system.

For instance, we can output the name of an S3 bucket or the domain name of an API.

In order to define Outputs in AWS CDK, we use the CfnOutput construct.

The code for this article is available on GitHub

To demo using outputs, I'll create a simple CDK stack, which consists of a single S3 bucket:

import * as s3 from 'aws-cdk-lib/aws-s3'; 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); // 👇 define the bucket const s3Bucket = new s3.Bucket(this, 'avatars-bucket', { removalPolicy: cdk.RemovalPolicy.DESTROY, }); // 👇 create an Output new cdk.CfnOutput(this, 'bucketName', { value: s3Bucket.bucketName, description: 'The name of the s3 bucket', exportName: 'avatarsBucket', }); } }

In the code snippet, we:

  1. Used the Bucket construct to define an S3 bucket
  2. Used the CfnOutput construct to create an output

Note that the output key is inferred from the id parameter we've passed to the CfnOutput construct. In our case, the key is bucketName.

The CfnOutput construct accepts the following props:

  • value - the value of the output
  • description - a short description of the output value
  • exportName - the name of the output that will be used in cross stack references
  • condition - if the condition prop evaluates to false, the output is not set for the stack

I'll deploy the stack with:

npx aws-cdk deploy

The generated CloudFormation templates for a CDK application are stored in the cdk.out directory. Let's take a look:

cdk out outputs

We can see that the output we've created in our CDK stack has successfully been translated to CloudFormation.

Let's take a look at the Outputs section in the CloudFormation console:

cloudformation outputs

In the screenshot we see that the name of the S3 bucket has been resolved as the output's value.

However, an important thing to note - we don't have access to the resolved value of an Output in our CDK code.

Let's try to assign our Output to a variable and console.log the result:

// 👇 assign Output to a variable const bucketNameOutput = new cdk.CfnOutput(this, 'bucketName', { value: s3Bucket.bucketName, description: 'The name of the s3 bucket', exportName: 'avatarsBucket', }); console.log('bucketNameOutput 👉', bucketNameOutput.value);

In the code snippet:

  1. We've assigned the Output to a variable
  2. We've passed the Output value to a console.log call

Let's synthesize the stack:

npx aws-cdk synth

Let's look at the output value:

output token

We can see that we've logged a Token. A token is an encoded value that will be resolved by CloudFormation at deployment time. I've written an article - What is a Token in AWS CDK if you want to read more.

This means that we are unable to access the resolved value of an output in our CDK code and we shouldn't try to use it in conditional statements.

Writing Output values to a File in CDK #

It's a common use case to have to write output values to a file on the local file system. We can then import these values from our frontend code.

This helps keep the AWS resource identifiers (i.e. bucket name, API url, Cognito User pool id) in sync between our backend and frontend code.

In order to write our output values to a file we have to pass the --outputs-file flag to the cdk deploy command.

npx aws-cdk deploy YOUR-STACK-NAME --outputs-file ./cdk-outputs.json

If we run the command we'll write all of our CDK stack's outputs to a file called cdk-outputs.json, located in the root directory of our project.

Let's take a look at the contents of the cdk-outputs.json file:

cdk outputs json

We can see that the CDK CLI has written the outputs to the file in the format:

{ "stack-name": { "output-name-1": "output-value-1", "output-name-2": "output-value-2" } }

This enables us to import the json file from our frontend and keep the resource identifiers between our frontend and backend code in sync.

Further Reading #

Use the search field on my Home Page to filter through my more than 3,000 articles.