Skip to content

feat: removeDependency#2872

Merged
cdklabs-automation merged 2 commits into
10.xfrom
huijbers/remove-dependency
Jul 15, 2026
Merged

feat: removeDependency#2872
cdklabs-automation merged 2 commits into
10.xfrom
huijbers/remove-dependency

Conversation

@rix0rrr

@rix0rrr rix0rrr commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Node has addDependency, but not removeDependency.

I am going to deprecate some dependency removal functions from AWS CDK, because those have been specified way too broadly and operate in a way that will make it hard to guarantee that dependency removal doesn't accidentally remove unintended dependencies.

However, we do need a non-deprecated replacement for that operation, which we will place at the construct tree level.

Node has `addDependency`, but not `removeDependency`.

I am going to deprecate some dependency removal functions from AWS CDK,
because those have been specified way too broadly and operate in a way
that will make it hard to guarantee that dependency removal doesn't
accidentally remove unintended dependencies.

However, we do need a non-deprecated replacement for that operation,
which we will place at the construct tree level.
@rix0rrr
rix0rrr requested a review from a team July 15, 2026 09:51
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@cdklabs-automation
cdklabs-automation added this pull request to the merge queue Jul 15, 2026
Merged via the queue into 10.x with commit 67495a0 Jul 15, 2026
12 checks passed
@cdklabs-automation
cdklabs-automation deleted the huijbers/remove-dependency branch July 15, 2026 16:02
mergify Bot pushed a commit to aws/aws-cdk that referenced this pull request Jul 17, 2026
`source.node.addDependency(target)` is used to confer dependencies between all resources under `source` to all resources under `target`.

The way this was done is to first expand the two sets into a Cartesian product, and then apply the dependency individually for each pair. The applied dependency can lead to a CloudFormation `DependsOn` relationship between the target resource (or the Nested Stack containing it), or a Stack-to-Stack dependency if the resources are in different stacks.

However, if this method of adding dependencies is applied to Stacks, we would first make all pairs of resources from `(sourceStack, targetStack)`, apply the dependency, and find out that each of those dependencies would ultimately just lead to a single stack-to-stack dependency. This method of applying dependencies is quadratic in the size of the stack, whereas it should be linear in the number of stack-to-stack dependencies applied.

In this PR, we rework the dependencies mechanism to remove the quadraticness if `node.addDependency` is used to add dependencies between stacks: we resolve the constructs that should be involved in the dependency operation first, and only expand to the cartesian product of individual resources if we end up inside the same Stack (in which case the construct groups are on the order of single digits). This makes the cross-stack case a *lot* faster.

(Note: I'm saying "superlinear" in the body because although it seems like the work should be quadratic, from testing it seems to be a lot worse than quadratic -- perhaps even exponential. In any case anything worse than linear is baaaaaddd so that's what I'm writing it down as 😉 )

Because there are multiple ways of adding dependencies, renamed some of them to make the distinction more clear:

- `construct.node.addDependency(construct)`: add a construct-level description of a dependency that will get reified at synthesis time.
  - That functionality gets a `removeDependency` here: aws/constructs#2872
- `stack.addStackDependency(stack)`, `resource.addResourceDependency(resource)`: directly applies a dependencies between stacks or resources.
  - These used to be called `stack.addDependency` and `resource.addDependency`, which is confusing because now  `stack.addDependency` and `stack.node.addDependency` look very similar but do very different things. So I renamed them.
  - Unfortunately `resource.addResourceDependency` also performs for cross-stack dependencies, which I'd much prefer it hadn't so it could stay simple and predictable, but we can't take this away anymore.
- Because we need to account for resource dependencies leading to stack dependencies (grr), we need to make a distinction between public API and mutation API, which are now under `_addStackDependency`, `_addResourceDependency` etc.

The flow is now this:

```
┌───────────────────┐       ┌───────────────────┐      ┌───────────────────┐
│                   │       │stack.addStackDepen│      │resoure.addResource│
│node.addDependency │       │       dency       │      │    Dependency     │
│                   │       │                   │      │                   │
└───────────────────┘       └───────────────────┘      └───────────────────┘
          │                           │                          │          
   (at synth time)              (immediately)              (immediately)    
          └───────────────────────────┼──────────────────────────┘          
                                      │                                     
                                      ▼                                     
                    ┌───────────────────────────────────┐                   
                    │                                   │                   
                    │    dispatchDependencyOperation    │                   
                    │                                   │                   
                    └───────────────────────────────────┘                   
                                      │                                     
                                      │                                     
                        ┌─────────────┴────────────┐                        
                        │                          │                        
                        │                          │                        
                        ▼                          ▼                        
              ┌───────────────────┐      ┌───────────────────┐              
              │stack._addStackDepe│      │resoure._addResourc│              
              │      ndency       │      │    eDependency    │              
              │                   │      │                   │              
              └───────────────────┘      └───────────────────┘              
```

Everything dispatches through the same code so that the behavior is the same regardless of the entry API that is chosen.

CHEAKING BRANGE: This PR removes `obtainResourceDependencies`; this was used as an internal function with nonstandard semantics. It has been moved to fully internal and is no longer usable externally (using different words because there is no way for me to format the PR title for a break in a way that the PR linter accepts). I tried `fix!:`` and `fix(core)!` and it keeps on complaining that there's something wrong. So I'm giving up.

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants