aws / aws/aws-cdk

aws-cdk/aws-s3: cyclic dependency created when adding bucket inventory config cross-stack in a stage

Open
#25,605 7 comments 0 reactions 0 assignees View on GitHub
@aws-cdk/aws-s3 bug effort/small p2
Dominant language
TypeScript
Stars
12.9k
Forks
4.6k
Avg merge
1d 19h
Merged PRs (30d)
74

Description

### Describe the bug

A cyclic dependency is created when:

* a stage is created, with two stacks (A and B)
* a bucket (A) is created in stack A
* another bucket (B) is created in stack B
* bucket B is configured to write inventory reports to bucket A

### Expected Behavior

Buckets should be able to add an inventory config referencing another bucket cross-stack.

### Current Behavior

Adding a cross-stack bucket inventory config inside a stage creates a cyclic dependency, causing the build to fail.

### Reproduction Steps

* create a stage
* create a stack containing a bucket (A) inside the stage
* create another stack containing a bucket (B) inside the stage
* call `bucket.addInventory()` on bucket B, setting bucket A as the destination

### Possible Solution

I think the issue occurs because of this code here: https://github.com/aws/aws-cdk/blob/b885ece7285ebe8219dbe4d62ae80554bd657632/packages/aws-cdk-lib/aws-s3/lib/bucket.ts#L2357-L2372

Essentially, the lib is trying to be helpful and add a policy on the destination bucket to make sure the source bucket can write to the destination correctly. However, there is no way to disable this behaviour if for example you want to manage your own bucket policies in the stacks separately. Doing so would allow me to remove the cyclic dependency.

Alternatively, allowing the user to optionally pass a bucket name instead of the entire `Bucket` object to the `s3.InventoryDestination` would allow this cycle to be broken.

### Additional Information/Context

A workaround is to move the buckets to both be on the same stack.

I found another workaround which was to do something like this:

```typescript
// this silly lookup avoids a cyclic dependency between stacks
const inventoryBucketArn = s3.Bucket.fromBucketArn(this, 'inventory-bucket', inventoryBucket.bucketArn);

this.bucket.addInventory({
destination: {
bucket: inventoryBucketArn,
bucketOwner: '',
},
frequency: s3.InventoryFrequency.DAILY,
includeObjectVersions: s3.InventoryObjectVersion.ALL,
});
```

The `Bucket.fromBucketArn()` static method returns an `IBucket` which does not trigger the addition of the inline policy on the destination bucket.

### CDK CLI Version

2.79.1

### Framework Version

_No response_

### Node.js Version

19

### OS

Linux

### Language

Typescript

### Language Version

_No response_

### Other information

_No response_

Contributor guide

Open the contributing guide

Research direction

Start with packages/aws-cdk-lib/aws-s3/lib/bucket.ts at lines 2357-2372 and reproduce the reported stage with two stacks, buckets A and B, and bucket B's addInventory configuration targeting A. Confirm the cyclic dependency during synthesis, then verify that cross-stack inventory configuration can complete without the cycle while retaining the expected destination permissions behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, typescript
Domain
cloud, infrastructure
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.