Last updated: Jan 26, 2024
Reading timeยท4 min
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.
To define Outputs in AWS CDK, we use the CfnOutput construct.
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 sample, we:
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 the deploy
command.
npx aws-cdk deploy
The generated CloudFormation templates for a CDK application are stored in the
cdk.out
directory. Let's take a look.
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.
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 sample:
Output
to a variable.Output
value to a console.log
call.Let's synthesize the stack.
npx aws-cdk synth
Let's look at the output value.
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.
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:
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.
We often need to use outputs in our CDK stack and redirect the output to a file, so that we can then import some of the AWS resource identifiers in our frontend code (i.e. API Gateway URL, etc).
To write CDK Outputs to a file we have to:
--outputs-file
flag when issuing the cdk deploy
command to write
the output values to a fileHere is a simple example of a CDK stack that provisions an Output with the value of the region from the current CDK environment.
import * as cdk from 'aws-cdk-lib'; export class CdkStarterStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); new cdk.CfnOutput(this, 'region', {value: cdk.Stack.of(this).region}); } }
cdk-v1
branch in the GitHub repository.Let's redirect the outputs from the stack to a file called cdk-outputs.json
located in the root directory.
Run the npx aws-cdk deploy
command and specify the --outputs-file
flag.
npx aws-cdk deploy YOUR-STACK-NAME \ --outputs-file ./cdk-outputs.json
After running the deploy
command, the cdk-outputs.json
file will be created
in the root directory of your CDK App. The file's contents include your default
AWS region, i.e.:
{ "cdk-stack": { "region": "us-east-1" } }
The best way to keep our AWS resource identifiers in sync between the frontend and backend is to redirect our CDK outputs to a file, which can be directly imported and read from the frontend.
You can learn more about the related topics by checking out the following tutorials: