I tried filtering aws-generated-tags added to S3 event notifications with EventBridge
This page has been translated by machine translation. View original
Introduction
An aws-generated-tags field has been added to Amazon S3 event notifications. When system-generated tags applied by AWS services are attached to a bucket, those tags are now included in the event and can be used for filtering in EventBridge.
| Aspect | Before | After Update |
|---|---|---|
| Information included in events | Bucket name, object key, size, etc. | Same as before + aws-generated-tags (system-generated tags for the bucket) |
| Filtering method | Individually listing bucket names | Can filter by tag values in aws-generated-tags (such as stack name) |
I was curious about what would actually be included, so I verified this across 3 bucket patterns and also tested the filtering behavior in EventBridge.
Verification Details
Verification Environment and Configuration
I created 3 types of buckets and an EventBridge rule using the following CloudFormation template.
CloudFormation template excerpt (S3 bucket and EventBridge rule section)
Resources:
# Pattern 1: CFn system tags only (no Tags property)
BucketCfnTagsOnly:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub 's3-evt-verify-cfn-only-${Suffix}'
NotificationConfiguration:
EventBridgeConfiguration:
EventBridgeEnabled: true
# Pattern 2: With user-defined tags
BucketWithUserTags:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub 's3-evt-verify-user-tags-${Suffix}'
NotificationConfiguration:
EventBridgeConfiguration:
EventBridgeEnabled: true
Tags:
- Key: Project
Value: blog-verification
- Key: Team
Value: devio
# Pattern 3: For manually adding tags (put-bucket-tagging after deployment)
BucketManualTag:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub 's3-evt-verify-manual-tag-${Suffix}'
NotificationConfiguration:
EventBridgeConfiguration:
EventBridgeEnabled: true
# EventBridge rule that filters by aws-generated-tags
FilterRule:
Type: AWS::Events::Rule
Properties:
Name: !Sub 's3-evt-verify-filter-rule-${Suffix}'
State: ENABLED
EventPattern:
source:
- aws.s3
detail-type:
- Object Created
detail:
bucket:
aws-generated-tags:
aws:cloudformation:stack-name:
- s3-evt-awsgentags-verify
Targets:
- Id: FilterSQSTarget
Arn: !GetAtt FilterQueue.Arn
# FilterQueue (AWS::SQS::Queue) and QueuePolicy are omitted
The 3 bucket patterns were each created with different tag states to verify what would be included in aws-generated-tags.
| Pattern | Bucket | Tag State | Verification Focus |
|---|---|---|---|
| 1 | BucketCfnTagsOnly | aws:cloudformation:* only (no Tags property) |
What goes into aws-generated-tags with only system tags |
| 2 | BucketWithUserTags | aws:cloudformation:* + Project, Team (CFn Tags) |
Whether user-defined tags are included in aws-generated-tags |
| 3 | BucketManualTag | aws:cloudformation:* + ManualTag (manually added) |
Whether manually added tags are included in aws-generated-tags |
Contents of the aws-generated-tags Field
I PUT an object into each pattern and compared the aws-generated-tags field of the received events.
| Pattern | Bucket Tag State | Tags Included in aws-generated-tags |
|---|---|---|
| 1. CFn system tags only | aws:cloudformation:* only |
aws:cloudformation:stack-name, stack-id, logical-id |
| 2. User-defined tags via CFn Tags | aws:cloudformation:* + Project, Team |
aws:cloudformation:stack-name, stack-id, logical-id (Project and Team not included) |
| 3. Manually added tags | aws:cloudformation:* + ManualTag |
aws:cloudformation:stack-name, stack-id, logical-id (ManualTag not included) |
For the CloudFormation-managed buckets verified this time, only the system-generated tags applied by CloudFormation were included in aws-generated-tags. Specifically, the results were as follows.
- Included:
aws:cloudformation:stack-name,aws:cloudformation:stack-id,aws:cloudformation:logical-id - Not included: User tags defined in the
Tagsproperty ofAWS::S3::Bucket, tags manually added viaput-bucket-tagging
In the Pattern 1 event, aws-generated-tags contained the 3 CloudFormation system tags.
"bucket": {
"name": "s3-evt-verify-cfn-only-20260717",
"aws-generated-tags": {
"aws:cloudformation:stack-id": "arn:aws:cloudformation:ap-northeast-1:123456789012:stack/s3-evt-awsgentags-verify/aa15e5b0-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"aws:cloudformation:logical-id": "BucketCfnTagsOnly",
"aws:cloudformation:stack-name": "s3-evt-awsgentags-verify"
}
}
In Pattern 2, even though Project and Team tags were attached to the bucket, the types of tag keys included in aws-generated-tags were the same as in Pattern 1.
"bucket": {
"name": "s3-evt-verify-user-tags-20260717",
"aws-generated-tags": {
"aws:cloudformation:stack-id": "arn:aws:cloudformation:ap-northeast-1:123456789012:stack/s3-evt-awsgentags-verify/aa15e5b0-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"aws:cloudformation:logical-id": "BucketWithUserTags",
"aws:cloudformation:stack-name": "s3-evt-awsgentags-verify"
}
}
In Pattern 3 as well, even though ManualTag was manually added via put-bucket-tagging, the types of tag keys included in aws-generated-tags were the same as in Patterns 1 and 2.
"bucket": {
"name": "s3-evt-verify-manual-tag-20260717",
"aws-generated-tags": {
"aws:cloudformation:stack-id": "arn:aws:cloudformation:ap-northeast-1:123456789012:stack/s3-evt-awsgentags-verify/aa15e5b0-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"aws:cloudformation:logical-id": "BucketManualTag",
"aws:cloudformation:stack-name": "s3-evt-awsgentags-verify"
}
}
Full event JSON (Pattern 1: CFn system tags only)
{
"version": "0",
"id": "167f17bc-a5c7-74a0-b542-6f66e8007f69",
"detail-type": "Object Created",
"source": "aws.s3",
"account": "123456789012",
"time": "2026-07-16T19:46:12Z",
"region": "ap-northeast-1",
"resources": ["arn:aws:s3:::s3-evt-verify-cfn-only-20260717"],
"detail": {
"version": "0",
"event-version": "1.1",
"bucket": {
"name": "s3-evt-verify-cfn-only-20260717",
"aws-generated-tags": {
"aws:cloudformation:stack-id": "arn:aws:cloudformation:ap-northeast-1:123456789012:stack/s3-evt-awsgentags-verify/aa15e5b0-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"aws:cloudformation:logical-id": "BucketCfnTagsOnly",
"aws:cloudformation:stack-name": "s3-evt-awsgentags-verify"
}
},
"object": {
"key": "test-cfn-only.txt",
"size": 14,
"etag": "0c78c972ee4ad0cc767914a4a9235b55",
"sequencer": "006A593504D0B0A5C4"
},
"request-id": "4E4R5T282H6KN86C",
"requester": "123456789012",
"source-ip-address": "203.0.113.1",
"reason": "PutObject"
}
}
Full event JSON (Pattern 2: User-defined tags via CFn Tags)
{
"version": "0",
"id": "7ca7ec54-8fd1-daf6-562c-37b2940f5a86",
"detail-type": "Object Created",
"source": "aws.s3",
"account": "123456789012",
"time": "2026-07-16T19:46:13Z",
"region": "ap-northeast-1",
"resources": ["arn:aws:s3:::s3-evt-verify-user-tags-20260717"],
"detail": {
"version": "0",
"event-version": "1.1",
"bucket": {
"name": "s3-evt-verify-user-tags-20260717",
"aws-generated-tags": {
"aws:cloudformation:stack-id": "arn:aws:cloudformation:ap-northeast-1:123456789012:stack/s3-evt-awsgentags-verify/aa15e5b0-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"aws:cloudformation:logical-id": "BucketWithUserTags",
"aws:cloudformation:stack-name": "s3-evt-awsgentags-verify"
}
},
"object": {
"key": "test-user-tags.txt",
"size": 15,
"etag": "a9cd14919053d9c5045b54398d42009d",
"sequencer": "006A5935054DC23AD2"
},
"request-id": "SZ06S3BAMTXTF0JH",
"requester": "123456789012",
"source-ip-address": "203.0.113.1",
"reason": "PutObject"
}
}
Full event JSON (Pattern 3: Manually added tags)
{
"version": "0",
"id": "f487191c-2aa0-397c-707c-3722670de533",
"detail-type": "Object Created",
"source": "aws.s3",
"account": "123456789012",
"time": "2026-07-16T19:46:13Z",
"region": "ap-northeast-1",
"resources": ["arn:aws:s3:::s3-evt-verify-manual-tag-20260717"],
"detail": {
"version": "0",
"event-version": "1.1",
"bucket": {
"name": "s3-evt-verify-manual-tag-20260717",
"aws-generated-tags": {
"aws:cloudformation:stack-id": "arn:aws:cloudformation:ap-northeast-1:123456789012:stack/s3-evt-awsgentags-verify/aa15e5b0-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"aws:cloudformation:logical-id": "BucketManualTag",
"aws:cloudformation:stack-name": "s3-evt-awsgentags-verify"
}
},
"object": {
"key": "test-manual-tag.txt",
"size": 16,
"etag": "975330f671d4c7fae808cf1e95a901ef",
"sequencer": "006A593505C645201C"
},
"request-id": "SZ03VKFY5AY8DXSV",
"requester": "123456789012",
"source-ip-address": "203.0.113.1",
"reason": "PutObject"
}
}
Stack Name-Based Filtering in EventBridge
Using aws-generated-tags, I configured an EventBridge rule to capture only events from buckets created by a specific CloudFormation stack. The field name is kebab-case (aws-generated-tags), and it is located under detail.bucket rather than at the top level of the event. Therefore, in the event pattern, it is specified using the path detail.bucket.aws-generated-tags.
{
"source": ["aws.s3"],
"detail-type": ["Object Created"],
"detail": {
"bucket": {
"aws-generated-tags": {
"aws:cloudformation:stack-name": ["s3-evt-awsgentags-verify"]
}
}
}
}
I ran 3 tests with this rule. In Test 2, I added a new bucket with EventBridge notifications enabled (BucketNewAdded) to the same stack, deployed a stack update, and verified whether events would be captured without changing the EventBridge rule.
| Test | Operation | Expected | Result |
|---|---|---|---|
| 1. PUT to bucket within the stack | PUT filter-v2-test1.txt to BucketCfnTagsOnly |
Reaches the filtering queue | ✅ PASS |
| 2. PUT to newly added bucket (no rule changes) | PUT filter-v2-test2.txt to BucketNewAdded |
Reaches the filtering queue | ✅ PASS |
| 3. PUT to bucket outside the stack (no CFn tags) | PUT external-test.txt to an external bucket |
Does not reach the filtering queue | ✅ PASS |
If you add a bucket with EventBridge notifications enabled to the same stack, its events can also be captured without changing the rule.
Summary
Using aws-generated-tags, you can filter S3 events by CloudFormation stack unit rather than by bucket name.
In configurations where multiple S3 buckets are managed in the same stack and their Object Created events are aggregated to a common destination, using the stack name as the condition keeps rules concise. In this verification, even when a bucket with EventBridge notifications enabled was added to the same stack, events could be captured without modifying the EventBridge rule. This is useful in stacks where bucket additions are anticipated and you want to reduce the overhead of managing individual bucket names.
