aws-cdk/aws-s3: cyclic dependency created when adding bucket inventory config cross-stack in a stage
- 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
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