EventBridge is a serverless event bus that makes it easy to connect applications together using data from your own applications, SaaS applications, and AWS services. Granting IAM permissions to publish events to EventBridge involves creating an IAM policy that allows specific actions on EventBridge resources.
Let’s see an example of an IAM policy that grants permissions to publish events to a specific EventBridge event bus.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "events:PutEvents",
"Resource": "arn:aws:events:us-east-1:123456789012:event-bus/my-custom-event-bus"
}
]
}
This policy allows the events:PutEvents action on the specified event bus ARN. The PutEvents action is the API call used to send events to EventBridge. The Resource element specifies the ARN of the event bus that the principal (user, role, or group) is allowed to publish events to.
Here’s how you would attach this policy to an IAM role that an EC2 instance or Lambda function might assume.
-
Create an IAM Role: If you don’t already have a role for your application, create one. For example, if this is for a Lambda function:
- Navigate to the IAM console.
- Click "Roles" in the left navigation pane.
- Click "Create role".
- Select "AWS service" as the trusted entity and "Lambda" as the use case.
- Click "Next".
-
Attach the Permissions Policy:
- On the "Add permissions" page, search for the policy you created (or create a new inline policy).
- Select the policy.
- Click "Next".
-
Name and Create the Role:
- Give your role a descriptive name, e.g.,
MyEventBridgePublisherRole. - Click "Create role".
- Give your role a descriptive name, e.g.,
Now, any Lambda function configured to assume this role will have the necessary permissions to publish events to your my-custom-event-bus.
The core of publishing events to EventBridge lies in the PutEvents API call. This API accepts an array of PutEventsRequestEntry objects, where each entry represents a single event. Key fields within an entry include:
Source: An identifier for the event producer. This is often a service name or application identifier (e.g.,com.mycompany.myapp).DetailType: A discriminator for the event within a given source. This helps consumers differentiate between different types of events from the same source (e.g.,UserCreated,OrderShipped).Detail: A JSON string containing the event payload. This is where your custom data goes.EventBusName: (Optional, if publishing to a custom bus) The name of the event bus to send the event to. If omitted, the default event bus is used.
Consider an application that needs to signal when a new user signs up. The application, running on an EC2 instance, would use the AWS SDK to construct and send an event.
import boto3
import json
def publish_user_created_event(user_id, email):
client = boto3.client('events')
response = client.put_events(
Entries=[
{
'Source': 'com.mycompany.userservice',
'DetailType': 'UserCreated',
'Detail': json.dumps({
'userId': user_id,
'email': email,
'timestamp': '2023-10-27T10:00:00Z'
}),
'EventBusName': 'my-custom-event-bus'
},
]
)
print(f"PutEvents response: {response}")
# Example usage:
# publish_user_created_event('user-123', 'test@example.com')
This Python code snippet demonstrates how to use the boto3 SDK to publish an event. It defines the Source, DetailType, and the Detail payload, and specifies the target EventBusName. The IAM role assumed by the EC2 instance running this code must have the events:PutEvents permission for my-custom-event-bus.
Beyond PutEvents, you might also need events:PutRule and events:PutTargets if your application is responsible for creating the rules and targets that consume these events. However, for simply publishing, PutEvents is the primary permission.
The most surprising truth about event publishing is that you don’t actually need a rule to exist on the destination event bus for PutEvents to succeed. The PutEvents operation is solely concerned with delivering the event to the bus. Event filtering and routing are handled by rules and targets after the event has been accepted by the bus. This separation of concerns means your event producers can be completely decoupled from the consumers and their routing logic.
When you call PutEvents, the AWS EventBridge service performs a quick validation of the event structure and the caller’s IAM permissions. If valid, it acknowledges the request immediately. The actual processing, including matching against rules and invoking targets, happens asynchronously in the background. This is why PutEvents is very fast and highly scalable.
A common point of confusion is the difference between the default event bus and custom event buses. If you omit the EventBusName in your PutEvents call, the event is sent to the default event bus in your AWS account for that region. Custom event buses are useful for organizing events from different sources or applications, providing better isolation and management. To publish to a custom event bus, the IAM policy must explicitly grant events:PutEvents on the ARN of that specific custom bus.
If your PutEvents calls start failing with AccessDeniedException despite having an IAM policy that looks correct, double-check that the Resource ARN in your policy precisely matches the target event bus ARN, including the region and account ID. Also, ensure the IAM role or user making the call is indeed assuming the correct role with that policy attached.
The next challenge you’ll likely encounter is how to efficiently filter and route these published events to specific downstream services, which involves creating and configuring EventBridge rules and targets.