Removing AWS CDK Cross-Stack Reference

Grigor Khachatryan
devgorilla
Published in
3 min readApr 4, 2024

--

When building applications on AWS, the Cloud Development Kit (CDK) simplifies the provisioning of resources and their dependencies. However, a common challenge developers face is dealing with cross-stack references. Cross-stack references occur when a resource in one stack (e.g., a S3 bucket in Stack1) is referenced by another stack (Stack2). While AWS CDK facilitates these references for ease of use, they can introduce deployment complexities, particularly when you wish to delete a resource that is being referenced across stacks. This guide will explain how to resolve such issues, focusing on a two-step deployment process to safely remove cross-stack references.

Understanding the Problem

Suppose you have two stacks, Stack1 and Stack2, where Stack1 includes an S3 bucket, and Stack2 references the bucket's name (bucket.bucketName). If you decide to remove the S3 bucket from Stack1, you might encounter an error similar to:

Export Stack1:ExportsOutputFnGetAtt-****** cannot be deleted as it is in use by Stack1

This error occurs because CloudFormation, which underlies CDK deployments, protects against the deletion of resources that are being referenced by other stacks. Directly removing the S3 bucket in Stack1 without addressing the reference in Stack2 would break Stack2, leading to potential application failures.

Solution: A Two-Step Deployment Process

To safely remove a cross-stack referenced resource, you need to follow a two-step deployment process. This approach ensures that the dependency is cleanly severed before the resource is deleted, avoiding deployment errors and application downtime.

Deployment 1: Break the Relationship

The first deployment focuses on eliminating the dependency between Stack2 and the S3 bucket in Stack1.

  1. Update Stack2: Modify Stack2 so that it no longer references the S3 bucket's name. This might involve switching to a different storage resource (like another S3 bucket or a DynamoDB table) or removing the dependent component altogether.
  2. Update Stack1: In the Stack1 class, call this.exportValue(this.bucket.bucketName);. This step ensures that the CloudFormation export for the bucket's name remains available even as you work to decouple the stacks. This is crucial for maintaining stability during the transition period.
  3. Deploy: Deploy both stacks. This deployment will primarily change Stack2, but it's a good practice to deploy Stack1 as well to enforce the export.

Deployment 2: Remove the Resource

Once the reference from Stack2 to the S3 bucket in Stack1 is removed, you can safely delete the bucket.

  1. Remove the Bucket: Delete the bucket resource from Stack1. Also, remove the exportValue() call you added in the first step.
  2. Deploy: Deploy Stack1. This deployment removes the S3 bucket, completing the process.

Example

Here’s a brief example to illustrate the steps above:

Before Modification

  • Stack1 contains:
const bucket = new s3.Bucket(this, 'MyBucket');
  • Stack2 references Stack1's bucket:
const bucketName = s3.Bucket.fromBucketName(this, 'ImportedBucket', 'stack1-bucket-name');

Deployment 1: Break the Relationship

  • Modify Stack2 to remove the reference to Stack1's bucket.
  • In Stack1, add:
this.exportValue(this.bucket.bucketName);

Deployment 2: Remove the Resource

  • Remove the S3 bucket from Stack1 and the exportValue() call.
  • Deploy Stack1.

By following these steps, you can smoothly handle cross-stack reference issues in AWS CDK, ensuring that your deployments are error-free and your infrastructure is easily manageable.

--

--