Resolve AWS CDK Stack Dependency Conflicts

The guide demonstrates how to resolve the conflicting stack dependencies in AWS CDK

Thursday, October 21, 2021

During the development of CDK applications, it is likely that you encounter the CDK stack dependencies and their conflicts. In this article we will understand why conflicts are created, and how to easily resolve them. To do so, let us define the demonstration application first.

The CDK App

The CDK source code of the demonstration application looks like

The application consists of the exporting and importing stack. Exporting stack creates the S3 bucket, which importing stack gets injected via constructor. Importing stack then uses buckets ARN property in its output value. This causes the dependency to be created between exporting and importing stack. Let us look to the CloudFormation template of the stacks to see why.

CloudFormation Templates

First let us examine the exporting stack template

CDKMetadata and Conditions sections were truncated as they are not important now. The template creates the output ExportsOutputFnGetAttExportedBucket5C9669B4ArnA5E36DA6 and exports it outside of the stack as exp:ExportsOutputFnGetAttExportedBucket5C9669B4ArnA5E36DA6. The exported value is the ARN of the bucket created in the exporting stack, obtained via the Fn:GetAtt function. The template of the importing stack looks like

We can see that importing stack is importing the export exp:ExportsOutputFnGetAttExportedBucket5C9669B4ArnA5E36DA6 by FnImportValue and using it in its output. This is creating the implicit stack dependency, as described at https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-dependson.html

    Dependent stacks also have implicit dependencies in the form of target properties !Ref and !GetAtt. 
    For example, if the properties of resource A use a !Ref to resource B, the following rules apply:

        Resource B is created before resource A.
        Resource A is deleted before resource B.
        Resource B is updated before resource A

CDK Deploy

Let us now deploy the importing stack, CDK CLI output looks like

Even though we invoked deployment on the importing stack, the exporting stack was deployed prior as well. This coheres to the CloudFormation documentation.

The Conflict

Let us now modify the CDK source code in following way

Importing stack no longer outputs the ARN of the bucket, but his domain name instead. CloudFormation templates are affected as following

Exporting bucket no longer exports exp:ExportsOutputFnGetAttExportedBucket5C9669B4ArnA5E36DA6, but exp:ExportsOutputFnGetAttExportedBucket5C9669B4DomainNameF044215B instead. Domain name export is imported by the importing stack. Let us now deploy the importing stack again, the output is following

Exporting stack can not be updated. Attempt to delete exp:ExportsOutputFnGetAttExportedBucket5C9669B4ArnA5E36DA6 fails, as it is still used by the importing stack (not in the CDK source code anymore, however still in the AWS itself).

The Resolution

In order to resolve the conflict, we need to keep the problematic export in the exporting stack until the importing stack will stop using it (in AWS). Below code shows how to do it

We created the CfnOutput construct manually in the exporting stack. The output logical identifier, value, and export name need to match the previously existing output for the ARN of the bucket. Export name is visible in the CloudFormation error, the output name and value can be looked up in the existing CloudFormation output list of the exporting stack. Examination of the CloudFormation templates confirms that exp:ExportsOutputFnGetAttExportedBucket5C9669B4ArnA5E36DA6 exists now only in the exporting stack.

The CDK deploy for the importing stack is now successful

Now that no stack in AWS depends on the S3 ARN output from exporting stack, we are finally free to remove it from CDK source code and execute CDK deploy

Only output for the S3 domain name exists now in the exporting stack. Although the process is slightly painful, after understanding the CloudFormation dependencies it is logical. I do hope that this article did come handy and will help you to resolve your CDK stack dependency issues.

Further Reading

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-stack-exports.html
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-dependson.html
https://aws-blog.de/2020/09/deployment-issues-with-cross-stack-dependencies-and-the-cdk.html