Use new CfnOutput(scope, id, { value }) to display a resource value after a CDK deployment. Set exportName only when another stack needs a named CloudFormation export. A resource's property can be passed directly to another construct without first making it an output.
Create an output in a complete stack
In a CDK v2 TypeScript project, use this stack and instantiate OutputStack from your app:
import { CfnOutput, Stack, StackProps } from "aws-cdk-lib"; import * as s3 from "aws-cdk-lib/aws-s3"; import { Construct } from "constructs"; export class OutputStack extends Stack { constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props); const bucket = new s3.Bucket(this, "Files", { blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL, }); new CfnOutput(this, "BucketName", { value: bucket.bucketName, description: "Private exercise bucket", exportName: `${this.stackName}-BucketName`, }); } }
The example uses bucketName, an actual bucket property. A bucket's website URL is relevant only when you intentionally configure website hosting; printing a URL does not make a private bucket publicly readable. See the CfnOutput API for supported properties.
Save and retrieve deployment outputs
npx aws-cdk deploy --outputs-file stack-outputs.json aws cloudformation describe-stacks --stack-name YOUR_STACK_NAME \ --query 'Stacks[0].Outputs' --output json
The output file groups values by stack name. A generated bucket name is generally unresolved during synthesis; CloudFormation fills it in during deployment. See CDK tokens for that distinction.
Import a named export in another stack
Inside the consuming stack, use the actual deployed producer stack name:
import { CfnOutput, Fn } from "aws-cdk-lib"; // Inside a consumer Stack constructor: const bucketName = Fn.importValue("YOUR_PRODUCER_STACK_NAME-BucketName"); new CfnOutput(this, "ReferencedBucketName", { value: bucketName });
This is an insertion snippet, not a standalone application. Deploy the producer before the consumer. Named exports must be unique within an account and region, and an exported value cannot be removed or changed while another stack imports it. Plan that lifecycle before using exports for interfaces that frequently change.
For two stacks in the same CDK application, passing an IBucket or another construct reference through stack props is often simpler: CDK can create the dependency and cross-stack references for you. Named exports are useful when the interface must be explicit across independently managed stacks.
Validation and cleanup
The complete stack targets CDK 2.272.0 and constructs 10.5.0. Type-check and synthesize it before deployment; the revision has not been deployed to AWS. Check that the template has an Outputs entry with Value and Export.Name. A passing synthesis does not verify cross-stack deployment order.
Do not output passwords or API tokens. Printing a bucket name also does not grant permissions: use grants or policies separately. When cleaning up, remove consumers before a producer whose exports they import. The bucket uses retention by default, so stack deletion can leave it behind for deliberate inspection.
Continue with CDK dependency ordering and cdk diff before changing deployed interfaces.
Quick Recap
How do you create a CDK output?
Instantiate CfnOutput with a string value. After deployment, CloudFormation exposes it in the stack's Outputs section.
How do you export an output?
Set exportName in the CfnOutput properties. Another stack in the same account and region can reference it with Fn.importValue. There is no CfnOutput.export() method.
Should secrets go in CloudFormation outputs?
No. Outputs are not a secret store. Output a secret ARN or name when appropriate, and retrieve its value through an authorized secret-management operation.
Comments
Share your thoughts and questions below