30.5 EventBridge Event Bus: Default, Custom, and Partner Event Buses
Alright, let’s talk about the grand central station for your event-driven architecture: the EventBridge Event Bus. Think of it less as a “bus” and more as the highly organized, slightly neurotic postal service for your events. It doesn’t just shove messages into a queue for you to poll; it receives an event, looks at its little rulebook, and routes it precisely to who or what needs to know. It’s the anti-SQS.
You get three flavors of this postal service: Default, Custom, and Partner. They’re all built on the same core machinery but have different security models and intended uses. Let’s break them down.
The Default Event Bus: Your Account’s Nervous System
Every AWS account gets a Default Event Bus for free. You don’t create it; it’s just… there. This bus is the central nervous system for events generated by AWS services themselves. When an EC2 instance terminates, when a CodePipeline execution changes state, when GuardDuty finds a threat—these events are all published to your Default Event Bus.
Its beauty is its simplicity, but its curse is its promiscuity. By default, any AWS service in your account can put events on it, and you can create rules to catch them. Here’s a rule that sends an email via SNS every time an EC2 instance is launched. Notice the eventPattern—it’s the bouncer that decides which events get into this particular rule’s club.
{
"awsEventsRule": {
"Type": "AWS::Events::Rule",
"Properties": {
"EventBusName": "default",
"Description": "Trigger on new EC2 instance launch",
"EventPattern": {
"source": ["aws.ec2"],
"detail-type": ["EC2 Instance State-change Notification"],
"detail": {
"state": ["running"]
}
},
"Targets": [{
"Arn": "arn:aws:sns:us-east-1:123456789012:alert-topic",
"Id": "MySNSTarget"
}]
}
}
}
The Pitfall: The biggest “gotcha” with the default bus is its open nature. It’s a firehose of every AWS service event. If you create a rule with too broad a pattern (or worse, no pattern), you might accidentally process a ton of events you don’t care about, racking up costs on unnecessary Lambda invocations or pointless logs. Be surgical with your patterns.
Custom Event Buses: For Your Stuff
The Default bus is for AWS’s stuff. A Custom Event Bus is for your stuff. This is where you isolate your application’s events. It’s a critical best practice for security, clarity, and cost management. You create it, you own it, and nothing can publish to it unless you explicitly allow it. This is your private, invite-only club.
Why bother? Separation of concerns. You don’t want your OrderShipped event getting lost in the noise of AWSConfigConfigurationSnapshotDeliveryCompleted. It also lets you set very granular resource-based policies on this single bus without affecting the AWS-generated events on the default bus.
Creating one is trivial. Using it is the key. Here’s how you’d send a custom event from a Lambda function to your custom bus.
import boto3
import json
client = boto3.client('events')
def lambda_handler(event, context):
# Your business logic here...
order_id = "12345"
# Put a custom event on our 'MyAppBus'
response = client.put_events(
Entries=[
{
'Source': 'my.application',
'DetailType': 'OrderShipped',
'Detail': json.dumps({'orderId': order_id, 'status': 'shipped'}),
'EventBusName': 'MyAppBus'
}
]
)
return response
The Insight: Notice the Detail field is a JSON string. This is the most common mistake—people pass a dictionary and get a serialization error. You have to json.dumps() it yourself. It feels a bit clunky, but that’s the API.
Partner Event Buses: The VIP Entrance
This is the weird one. Partner Event Buses are pre-configured conduits for events from SaaS companies that have partnered with AWS—think Datadog, Auth0, Shopify, or Zendesk. You don’t create these either; you “activate” them or find them in your account.
The key difference is the security model. These partners don’t have access to your AWS account to put events on your default or custom buses. Instead, they publish to an AWS-owned bus, and you create rules that forward events from that partner bus to a target in your account.
The Rough Edge: The configuration can feel a bit magical because AWS manages the other end. You’re just tapping into the stream. The event structure is also entirely defined by the partner, so you have to go find their documentation (which can be good or terrible) to build your pattern-matching rules. It’s powerful, but be prepared for some external docs-reading.
Best Practices from the Trenches
- Go Custom, Early: Start with a custom bus for your application events on day one. The default bus is for AWS operational events. Mixing them is a recipe for a tangled mess.
- Be Specific in Your Patterns: A pattern like
{ "source": ["aws.ec2"] }will catch every single EC2 event. You will get bills for things you didn’t know were happening. Drill down to thedetail-typeand specificdetailfields. - Mind the
EventBusPolicy: For custom and partner buses, the resource policy (theEventBusPolicyin Terraform or thePermissionmodel in CloudFormation) is what allows other accounts or services to write to it. This is how you do cross-account event sharing securely. If your event isn’t showing up, check the policy—it’s almost always a permissions issue. - Retry Logic is Your Job: While EventBridge has fantastic reliability (the events are stored in a multi-AZ database-backed store, which is AWS-speak for “incredibly durable”), the targets can fail. If your Lambda function throws an error, EventBridge will retry with exponential backoff for 24 hours. But after that? The event is gone. For mission-critical events, you must ship dead-letter events to an SQS queue or SNS topic to handle failures yourself. Don’t assume it’s all taken care of for you.