AWS Compute Blog
Filtering events in Amazon EventBridge with wildcard pattern matching
This post is written by Rajdeep Banerjee, Sr PSA, and Brian Krygsman, Sr. Solutions Architect.
Amazon EventBridge recently announced support for wildcard filters in rule event patterns. An EventBridge event bus is a serverless event router that helps you decouple your event-driven systems. You can route events between your systems, AWS services, or third-party SaaS services. You attach a rule to your event bus to define logic for routing events from producers to consumers.
You set an event pattern on the rule to filter incoming events to specific consumers. The new wildcard filter lets you build more flexible event matching patterns to reduce rule management and optimize your event consumers. This shows how these EventBridge attributes work together.
Wildcard filters use the wildcard character (*) to match zero, single, or multiple characters in a string value. For example, a filter string like "*.png"
matches strings that end with ".png"
.
You can also use multiple wildcard characters in a filter. For example, a filter string like "*Title*"
matches string values that include "Title"
in the middle. When using wildcard filters, be careful to avoid matching more events than you intend.
This blog post describes how you can use wildcard filters in example scenarios. For more information about event-driven architectures, visit Serverless Land.
Wildcard pattern matching in S3 Event Notifications
Applications must often perform an action when new data is available. One example can be to process trading data uploaded to your Amazon S3 bucket. The data may be stored in individual folders depending on the date, time, and stock symbol. Business rules may dictate that when stock XYZ receives a file, it must send a notification to a downstream system.
This is the typical folder structure in an S3 bucket:
S3 can send an event to EventBridge when an object is written to a bucket. The S3 event includes the object key (for example, 2023-10-01/T13:22:22Z/XYZ/filename.ext
). When any object is uploaded to the XYZ folder, you can use an EventBridge rule to send these events to a downstream service like an Amazon SQS.
Before this launch, you would first send the event to an AWS Lambda function. Existing prefix and suffix filters alone are insufficient because of the extra date and time folders. The function would run your code to inspect the object path for the stock symbol. Your code would then forward events to SQS when they matched.
With the new wildcard patterns in EventBridge rules, the logic is simpler. You no longer need to create a Lambda function to run custom matching code. You can instead use wildcard characters in the rule’s filter pattern, matching against portions of the S3 object key.
- To use this, start with creating a new rule in the EventBridge console:
- Choose Next. Keep the standard parameters and move to the Event pattern section. Here you can use a JSON-based event pattern.
{ "source": ["aws.s3"], "detail": { "bucket": { "name": ["intraday-trading-data"] }, "object": { "key": [{ "wildcard": "*/XYZ/*" }] } } }
- This pattern looks for Event Notifications from a specific bucket. The pattern then filters the events further by the object keys that match
"*/XYZ/*"
. The rule filters out notifications from other stock symbols, listening to only “XYZ“ data, irrespective of date and time of the data feed. - To use an SQS queue for the filtered event target, you must provide resource-based policies for EventBridge to send messages to the queue.
- Choose Next and review the rule details before saving.
- Before testing, enable S3 event notifications to EventBridge in the S3 console:
- To test the new wildcard pattern, upload any sample CSV file in the XYZ folder to launch the Event Notifications.
- You can monitor EventBridge CloudWatch metrics to check if the rule is invoked from the S3 upload. The SQS CloudWatch metrics show if messages are received from the EventBridge rule.
Filtering based on Amazon Resource Name (ARN)
Customers often need to perform actions when AWS Identity and Access Management (IAM) policies are added to specific roles. You can achieve this by creating custom EventBridge rules, which filter the event to match or create multiple rules to achieve the same effect. With the newly introduced wildcard filter, the task to invoke an action is simplified.
Consider an IAM role with fine-grained IAM policies attached. You may need to ensure any new policy attached to this role must be from a specific ARNs. This action can be implemented like this.
When you attach a new IAM policy to a role, it generates an event like this:
{
"version": "0",
"id": "0b85984e-ec53-84ba-140e-9e0cff7f05b4",
"detail-type": "AWS API Call via CloudTrail",
"source": "aws.iam",
"account": "123456789012",
"time": "2023-10-07T20:23:28Z",
"region": "us-east-1",
"resources": [],
"detail": {
"eventVersion": "1.08",
"userIdentity": {
"arn": "arn:aws:sts::123456789012:assumed-role/Admin/UserName",
// ... additional detail fields
},
"eventTime": "2023-10-07T20:23:28Z",
"eventSource": "iam.amazonaws.com",
"eventName": "AttachRolePolicy",
// ... additional detail fields
}
}
You can create a rule matching against a combination of these event properties. You can filter detail.userIdentity.arn
with a wildcard to catch events that come from a particular ARN. You can then route these events to a target like an Amazon CloudWatch Logs stream to record the change. You can also route them to Amazon Simple Notification Service (SNS). You can use the SNS notification to start a review and ensure that the newly attached policies are well-crafted as part of your reconciliation and audit process. The filter looks like this:
{
"source": ["aws.iam"],
"detail-type": ["AWS API Call via CloudTrail"],
"detail": {
"eventSource": ["iam.amazonaws.com"],
"eventName": ["AttachRolePolicy"],
"userIdentity": {
"arn": [{
"wildcard": "arn:aws:sts::123456789012:assumed-role/*/*"
}]
}
}
}
Filtering custom events
You can use EventBridge to build your own event-driven systems with loosely coupled, scalable application services. When building event-driven applications in AWS, you can publish events to the default event bus, or create a custom event bus. You define the structure of events emitted from your services.
This structure is known as the event schema. When you attach rules to your bus to route events from producers to consumers, you match against values from properties in your event schema. Wildcard filters allow you to match property values that are unknown ahead of time, or across multiple value variants.
Consider an ecommerce application as an example. You may have several decoupled services working together, like a shopping cart service, an inventory service, and others. Each of these services emits events onto your event bus as your customers shop.
Events may include errors, to record problems customers encounter using your system. You can use a single rule with a wildcard filter to match all error events and send them to a common target. This allows you to simplify observability across your services.
This is the event flow:
Your shopping cart service may emit a timeout error event:
{
"version": "0",
"id": "24a4b957-570d-590b-c213-2a72e5dc4c66",
"detail-type": "shopping.cart.error.timeout",
"source": "com.mybusiness.shopping.cart",
"account": "123456789012",
"time": "2023-10-06T03:28:44Z",
"region": "us-west-2",
"resources": [],
"detail": {
"message": "Operation timed out.",
"related-entity": {
"entity-type": "order",
"id": "123"
},
// ... additional detail fields
}
}
The detail-type
property of the example event determines what type of event this is. Other services may emit error events with different prefixes in detail-type
. Other error types might have different suffixes in detail-type
.
For example, an inventory service may emit an out-of-stock error event like this:
{
"version": "0",
"id": "e456f480-cc1e-47fa-8399-ab2e54116958",
"detail-type": "shopping.inventory.error.outofstock",
"source": "com.mybusiness.shopping.inventory",
"account": "123456789012",
"time": "2023-10-06T03:28:44Z",
"region": "us-west-2",
"resources": [],
"detail": {
"message": "Product cannot be added to a cart. Out of stock.",
"related-entity": {
"entity-type": "product",
"id": "456"
}
// ... additional detail fields
}
}
To route these events to a common target like an Amazon CloudWatch Logs stream, you can create a rule with a wildcard filter matching against detail-type. You can combine this with a prefix filter on source that filters events down to only services from your shopping system. The filter looks like this:
{
"source": [{
"prefix": "com.mybusiness.shopping."
}],
"detail-type": [{
"wildcard": "*.error.*"
}]
}
Without a wildcard filter you would need to create a more complex matching pattern, possibly across multiple rules.
Conclusion
Wildcard filters in EventBridge rules help simplify your event driven applications by ensuring the correct events are passed on to your targets. The new feature reduces the need for custom code, which was required previously. Try EventBridge rules with wildcard filters and experience the benefits of this new feature in your event-driven serverless applications.
For more serverless learning resources, visit Serverless Land.