How to share Resources between Stacks in AWS CDK


Borislav Hadzhiev

Fri Apr 15 20223 min read


Photo by redcharlie

Updated - Fri Apr 15 2022

Sharing Resources between Stacks in AWS CDK #

In order to share resources between stacks, in the same CDK app, we have to:

  1. assign the resources we want to share as class properties on stackA
  2. add the types of the class properties to the props object of stackB
  3. instantiate stackA, so we can access the class properties
  4. pass the stackA class properties as props when instantiating stackB
  5. reference the properties from the props object of stackB

Let's look at an example where we create 2 stacks and share an S3 bucket between them.

The code for this article is available on GitHub

The code snippet defines the following 2 CDK stacks:

  1. BucketStack provisions an S3 bucket
  2. LambdaStack creates a lambda function and references the shared bucket resource from the BucketStack
import * as lambda from 'aws-cdk-lib/aws-lambda'; import * as s3 from 'aws-cdk-lib/aws-s3'; import * as cdk from 'aws-cdk-lib'; import * as path from 'path'; export class BucketStack extends cdk.Stack { // 👇 set a property for the bucket public readonly bucket: s3.Bucket; constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); // 👇 assign an S3 bucket to the class property this.bucket = new s3.Bucket(this, 'my-bucket', { removalPolicy: cdk.RemovalPolicy.DESTROY, }); } } interface LambdaStackProps extends cdk.StackProps { bucket: s3.Bucket; } export class LambdaStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props: LambdaStackProps) { super(scope, id, props); const {bucket} = props; // 👇 tag the shared bucket cdk.Tags.of(bucket).add('environment', 'staging'); cdk.Tags.of(bucket).add('department', 'accounting'); const lambdaFunction = new lambda.Function(this, 'lambda-function', { runtime: lambda.Runtime.NODEJS_14_X, handler: 'index.main', code: lambda.Code.fromAsset(path.join(__dirname, '/../src/my-lambda')), environment: { // 👇 pass bucket name to lambda BUCKET_NAME: bucket.bucketName, }, }); } }

Let's go over the code snippet.

  1. We defined a BucketStack, which provisions an S3 bucket. The bucket resource is assigned as a class property, so we can access it when we instantiate the class.

  2. We extended the props object of our second stack, by adding the bucket type to it

  3. We defined our LambdaStack, which will receive the shared bucket in the props object. In our LambdaStack, we add some tags to the shared bucket and pass its name as an environment variable to a lambda function

The code for this article is available on GitHub

Now let's look at how we instantiate the CDK stacks:

import * as cdk from 'aws-cdk-lib'; import {BucketStack, LambdaStack} from '../lib/cdk-starter-stack'; const app = new cdk.App(); const bucketStack = new BucketStack(app, 'bucket-stack', { stackName: 'bucket-stack', env: { region: process.env.CDK_DEFAULT_REGION, account: process.env.CDK_DEFAULT_ACCOUNT, }, }); const lambdaStack = new LambdaStack(app, 'lambda-stack', { // 👇 pass the S3 bucket from the other stack bucket: bucketStack.bucket, stackName: 'lambda-stack', env: { region: process.env.CDK_DEFAULT_REGION, account: process.env.CDK_DEFAULT_ACCOUNT, }, });

We first instantiate the BucketStack and assign the instance to a variable.

We then instantiate the LambdaStack, passing in the S3 bucket.

At this point we can reference the bucket on the props object of our LambdaStack.

The code for this article is available on GitHub

Lastly, let's add the code for the lambda function at src/my-lambda/index.js:

async function main(event) { console.log('BUCKET_NAME 👉', process.env.BUCKET_NAME); return { body: JSON.stringify({message: `${process.env.BUCKET_NAME} 🎉`}), statusCode: 200, }; } module.exports = {main};

The lambda simply prints the name of the shared bucket.

When deploying the stacks, we have to make sure to deploy the BucketStack first because we are trying to reference it in our LambdaStack.

Let's deploy the stacks and look at the results:

npx aws-cdk deploy bucket-stack npx aws-cdk deploy lambda-stack

After the stacks have been deployed, we can see that CDK has automatically created an Output with the S3 bucket's name to enable us to reference it in our other stack:

bucket stack outputs

The Tags section of our shared S3 bucket shows that the tags we added to it from our second stack have been applied:

shared bucket tags

Finally, if we test our function via the Lambda management console, we can see that the function returns the name of the shared bucket:

shared bucket name

Clean up #

When deleting the stacks we have to first delete the LambdaStack and then the BucketStack because we can't delete a stack that exports an output that is referenced in another stack.

npx aws-cdk destroy lambda-stack npx aws-cdk destroy bucket-stack

Further Reading #

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