Skip to content

fix(aws/s3): link inline lifecycle/ITC/versioning configs to nameless buckets [FIX-304] - #71

Merged
liamg merged 1 commit into
mainfrom
fix/s3-inline-lifecycle-nameless-bucket
Jun 23, 2026
Merged

fix(aws/s3): link inline lifecycle/ITC/versioning configs to nameless buckets [FIX-304]#71
liamg merged 1 commit into
mainfrom
fix/s3-inline-lifecycle-nameless-bucket

Conversation

@drewblas

Copy link
Copy Markdown
Contributor

FIX-304

CloudFormation/CDK AWS::S3::Bucket resources with an inline LifecycleConfiguration but no explicit BucketName (the CDK default — the physical name is generated at deploy time) falsely fail the S3 lifecycle FinOps policies (aws-delete-multi-part-uploads-s3-lifecycle-configuration, aws-ensure-transition-rules-defined-s3-lifecycle-configuration).

Root cause

pkg/tree/aws/s3/s3.go PostProcess() joins lifecycle/ITC/versioning/policy configs to buckets via bucketMap, keyed on bucket name (skipped when empty) and bucket ID. Inline CFN configs carry an empty BucketName, so the join misses and the bucket ends up with zero Relationships.LifecycleConfigurations — the policies only iterate that relationship, so they report false failures.

Confirmed against the real parsed tree: a nameless bucket's inline lifecycle config has bucketName="" but id == "<bucket logical ID>" (identical to the bucket). That ID is already in bucketMap, it just wasn't consulted for the join.

Regression from the IaC-agnostic tree refactor (providers #74 / #90); pre-refactor code attached inline CFN rules directly to bucket.LifecycleRules, so no name join was needed.

Fix

In PostProcess(), fall back to matching a sub-resource by its own ID when the bucket-name match misses. Inline configs share the owning bucket's logical ID; standalone resources (separate lifecycle config / bucket policy) have distinct IDs and so never false-match. Applied to lifecycle, intelligent-tiering, versioning, and bucket-policy joins.

Tests

pkg/tree/aws/s3/s3_nameless_bucket_test.go — links inline configs to a nameless bucket by shared ID, and asserts a standalone config pointing at another bucket is not false-matched. Existing idempotency test still passes.

Downstream

providers regression tests live in #(providers PR, see FIX-304). Once this is released, bump go-proto in providers (go.mod + e2e/go.mod) to pick up the fix.

… buckets

CloudFormation/CDK S3 buckets usually have no explicit BucketName (the physical
name is generated at deploy time). Their inline configurations therefore carry
an empty bucket name, so the bucket<->config join in PostProcess (keyed only on
the referenced bucket name) dropped them. Buckets ended up with no
Relationships.LifecycleConfigurations, causing the S3 lifecycle FinOps policies
(delete-multipart-uploads, ensure-transition-rules) to report false failures.

Inline configs share the owning bucket's logical ID, which is already indexed in
bucketMap, so fall back to matching on the sub-resource's own ID when the bucket
name doesn't match. Standalone resources have distinct IDs and so never
false-match.
@drewblas
drewblas requested a review from liamg June 23, 2026 02:22
@liamg
liamg merged commit 0ea933e into main Jun 23, 2026
3 checks passed
@liamg
liamg deleted the fix/s3-inline-lifecycle-nameless-bucket branch June 23, 2026 08:31
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.

2 participants