Borislav Hadzhiev
Fri Apr 15 2022·3 min read
Photo by redcharlie
Updated - Fri Apr 15 2022
In order to share resources between stacks, in the same CDK app, we have to:
stackA
props
object of stackB
stackA
, so we can access the class propertiesstackA
class properties as props
when instantiating stackB
props
object of stackB
Let's look at an example where we create 2 stacks and share an S3 bucket between them.
The code snippet defines the following 2 CDK stacks:
BucketStack
provisions an S3 bucketLambdaStack
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.
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.
We extended the props
object of our second stack, by adding the bucket
type to it
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
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
.
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:
The Tags
section of our shared S3 bucket shows that the tags we added to it
from our second stack have been applied:
Finally, if we test our function via the Lambda management console, we can see that the function returns the name of the shared bucket:
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