[Feature Request](Stack Dependencies): stack dependency should also be hornoured during "cdk destroy"
- Dominant language
- TypeScript
- Stars
- 12.9k
- Forks
- 4.6k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 83
Description
### Describe the feature
If users claim stacks' variables in an order that is different from [Stack Dependencies](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib-readme.html#stack-dependencies) via addDependency/add_dependency, "cdk destroy --all" will incur dependency-related "Delete_failed" stacks.
### Use Case
Code examples in Python
app.py:
```
stack2 = CdkPythonStackotherStack(app, "cdk-python-second-stack", env = env)
stack1 = CdkPythonStack2Stack(app, "cdk-python-first-stack", env = env)
stack3 = CdkPythonStackThirdStack(app, "cdk-python-third-stack", env = env)
stack2.add_dependency(stack1)
stack3.add_dependency(stack1)
```
Additional restriction to trigger error if order wrong. In stack1 I am exporting an output
```
CfnOutput(self, "output", value = snsALL.topic_arn, export_name="snsGlobal")
```
In stack2 and stack3, I am importing the stack1-export to create CFN-side explicit dependency
```
snsALL=sns.Topic.from_topic_arn(self, 'topic', Fn.import_value('snsGlobal'))
```
As you can see app.py stack variables are claimed in order:
```
stack2
stack1
stack3
```
Whereas, the Stack Dependency is created as
```
stack1
|___ stack2
|___ stack3
```
During the `cdk deploy --all`, the stack1 always to be created first then following stack2/3.
However, during the `cdk destroy --all`, the only order destroy process is following is reverse order of the variables:
```
(.venv) Admin:~/environment/cdk_python_stack2 (master) $ cdk destroy --all
Are you sure you want to delete: cdk-python-third-stack, cdk-python-first-stack, cdk-python-second-stack (y/n)? y
```
it appears to be expected given current public `async destroy function` is coded [here](https://github.com/aws/aws-cdk/blob/0e808d81d8a6b4b860f9dbf6be6bdf85429eaf77/packages/aws-cdk/lib/cdk-toolkit.ts#L547) as:
```
// The stacks will have been ordered for deployment, so reverse them for deletion.
stacks = stacks.reversed();
```
Which gives rise to error:
```
cdk-python-third-stack: destroying... [1/3]
✅ cdk-python-third-stack: destroyed
cdk-python-first-stack: destroying... [2/3]
❌ cdk-python-first-stack: destroy failed Error: Failed to destroy cdk-python-first-stack: CREATE_COMPLETE (Export snsGlobal cannot be deleted as it is in use by cdk-python-second-stack)
at destroyStack (/home/ec2-user/.nvm/versions/node/v16.13.1/lib/node_modules/aws-cdk/lib/index.js:426:1796)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async CdkToolkit.destroy (/home/ec2-user/.nvm/versions/node/v16.13.1/lib/node_modules/aws-cdk/lib/index.js:429:161194)
at async exec4 (/home/ec2-user/.nvm/versions/node/v16.13.1/lib/node_modules/aws-cdk/lib/index.js:504:52657)
Failed to destroy cdk-python-first-stack: CREATE_COMPLETE (Export snsGlobal cannot be deleted as it is in use by cdk-python-second-stack)
```
### Proposed Solution
Update the the destroy function, to reverse the stacks order that [deploy function used based on Stack Dependencies](https://github.com/aws/aws-cdk/blob/0e808d81d8a6b4b860f9dbf6be6bdf85429eaf77/packages/aws-cdk/lib/cdk-toolkit.ts#L350C1-L354C98):
```
const stacksAndTheirAssetManifests = stacks.flatMap(stack => [
stack,
...stack.dependencies.filter(cxapi.AssetManifestArtifact.isAssetManifestArtifact),
]);
const workGraph = new WorkGraphBuilder(prebuildAssets).build(stacksAndTheirAssetManifests);
```
### Other Information
Maybe also consider update the [Stack Dependencies documentation](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib-readme.html#stack-dependencies) with a highlighted text states that currently the "destroy" is not following the dependency but merely reverse var-declaration order in code.
### Acknowledgements
- [ ] I may be able to implement this feature request
- [ ] This feature might incur a breaking change
### CDK version used
2.88.0
### Environment details (OS name and version, etc.)
Cloud9 latest
Contributor guide
Research direction
Start in packages/aws-cdk/lib/cdk-toolkit.ts at the public async destroy function and compare its ordering with the deploy path's WorkGraphBuilder usage. Trace how addDependency and the stack dependency graph are represented, then verify that cdk destroy --all deletes dependent stacks before their dependencies without the reported export failure. If documentation is included, update the linked Stack Dependencies guidance to describe destroy ordering.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, typescript
- Domain
- cli, devops, infrastructure
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 50/100