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