Last updated: Jan 26, 2024
Reading timeยท4 min

To reference a resource value from a different stack we use the Import Value static method on the Fn class.
First, we have to use an Output to export the value we'll eventually import.
In this example, I'll create an S3 Bucket and
export its name as an Output.
import * as lambda from 'aws-cdk-lib/aws-lambda'; import {NodejsFunction} from 'aws-cdk-lib/aws-lambda-nodejs'; import * as s3 from 'aws-cdk-lib/aws-s3'; import * as cdk from 'aws-cdk-lib'; import * as path from 'path'; export class S3BucketStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props: cdk.StackProps) { super(scope, id, props); const myBucket = new s3.Bucket(this, 'myBucket', { removalPolicy: cdk.RemovalPolicy.DESTROY, }); // ๐ export myBucket for cross-stack reference new cdk.CfnOutput(this, 'myBucketRef', { value: myBucket.bucketName, description: 'The name of the s3 bucket', exportName: 'myBucket', }); } } const app = new cdk.App(); new S3BucketStack(app, 'my-s3-stack', { stackName: 'my-s3-stack', env: { region: process.env.CDK_DEFAULT_REGION, account: process.env.CDK_DEFAULT_ACCOUNT, }, });
I'll now run the deploy command.
npx aws-cdk deploy my-s3-stack
If we take a look at the CloudFormation console and click on the Outputs
section of the stack, we can see that the exportName of the value we are going
to import is myBucket.

Next, let's use Import Value to import the bucket name into another stack and
pass it as an environment variable to a
Lambda function.
import * as lambda from 'aws-cdk-lib/aws-lambda'; import {NodejsFunction} from 'aws-cdk-lib/aws-lambda-nodejs'; import * as s3 from 'aws-cdk-lib/aws-s3'; import * as cdk from 'aws-cdk-lib'; import * as path from 'path'; export class MyCdkStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props: cdk.StackProps) { super(scope, id, props); const importedBucketValue = cdk.Fn.importValue('myBucket'); console.log('importedBucketValue ๐', importedBucketValue.toString()); const myFunction = new NodejsFunction(this, 'my-function', { // ๐ Pass the imported bucket name as env var environment: { BUCKET_NAME: importedBucketValue.toString(), }, runtime: lambda.Runtime.NODEJS_18_X, timeout: cdk.Duration.seconds(4), handler: 'main', entry: path.join(__dirname, `/../src/my-lambda/index.js`), }); } } const app = new cdk.App(); new MyCdkStack(app, 'my-cdk-stack', { stackName: 'my-cdk-stack', env: { region: process.env.CDK_DEFAULT_REGION, account: process.env.CDK_DEFAULT_ACCOUNT, }, });
The code of the Lambda function could be as simple as follows.
async function main(event) { console.log('BUCKET_NAME ๐', process.env.BUCKET_NAME); return {body: JSON.stringify({message: 'SUCCESS'}), statusCode: 200}; } module.exports = {main};
We used the
importValue
static method on the
Fnclass. The
only argument the method takes is the exportName of the value we want to
import.
I'll then issue the deploy command:
npx aws-cdk deploy my-cdk-stack
The call to console.log with the imported value prints a token:

Tokens in CDK are encoded values that get resolved at deployment time by CloudFormation. This means that we don't have access to the resolved value at synthesis time in our CDK code.
If we take a look at the lambda console, we can see that after we ran the
deploy command, the imported value has been resolved.

At this point, we were successfully able to use the importValue method to
import a value that was exported from a different stack.
Some of the restrictions when working with import value and cross-stack references are:
exportNames we use have to be unique within a region.For example, I'll try to delete the Output in the my-s3-bucket stack.
export class S3BucketStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props: cdk.StackProps) { super(scope, id, props); const myBucket = new s3.Bucket(this, 'myBucket', { removalPolicy: cdk.RemovalPolicy.DESTROY, }); // ๐ has been removed // new cdk.CfnOutput(this, 'myBucketRef', { // value: myBucket.bucketName, // description: 'The name of the s3 bucket', // exportName: 'myBucket', // }); } }
If I now run the cdk deploy command, I'd get the following error.
myBucket cannot be deleted as it is in use by my-cdk-stack
If we try to provision multiple Outputs with the same Export name, we would also get an error.
export class S3BucketStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props: cdk.StackProps) { super(scope, id, props); const myBucket = new s3.Bucket(this, 'myBucket', { removalPolicy: cdk.RemovalPolicy.DESTROY, }); new cdk.CfnOutput(this, 'myBucketRef', { value: myBucket.bucketName, description: 'The name of the s3 bucket', // ๐ same name exportName: 'myBucket', }); new cdk.CfnOutput(this, 'myBucketRef2', { value: myBucket.bucketName, description: 'The name of the s3 bucket', // ๐ same name exportName: 'myBucket', }); } }
If I now run the cdk deploy command it outputs the error message:

If we try to delete a stack that exports outputs that are imported by other stacks, we would also get an error:
myBucket cannot be deleted as it is in use by my-cdk-stack)
You can learn more about the related topics by checking out the following tutorials: