EventBridge events don’t just stay in their own AWS account by default; they can be a powerful way to communicate system state changes across your entire AWS footprint.
Let’s say you have a set of EC2 instances in Account-A that are launching and terminating based on demand. When an instance terminates, you want a Lambda function in Account-B to record that event to a database.
Here’s how we can set that up:
Account-A (Source Account):
-
Create an EventBridge Event Bus: You’ll need a custom event bus in your source account to act as the central hub for your events.
aws events create-event-bus --name MyCrossAccountBus --region us-east-1This creates a bus named
MyCrossAccountBusinus-east-1. -
Create a PutEvents Policy on the Bus: This policy grants
Account-Bpermission to put events ontoMyCrossAccountBusinAccount-A.- Go to the EventBridge console in
Account-A. - Select
MyCrossAccountBus. - Go to the "Permissions" tab.
- Click "Create policy".
- Use the following JSON, replacing
ACCOUNT_B_IDwith the actual AWS account ID ofAccount-B:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowAccountBToPutEvents", "Effect": "Allow", "Principal": { "AWS": "ACCOUNT_B_ID" }, "Action": "events:PutEvents", "Resource": "arn:aws:events:us-east-1:ACCOUNT_A_ID:event-bus/MyCrossAccountBus" } ] } - Go to the EventBridge console in
-
Create a Rule to Capture EC2 Terminations: This rule will match EC2 instance termination events and send them to
MyCrossAccountBus.- In EventBridge console in
Account-A, selectMyCrossAccountBus. - Click "Create rule".
- Name it
EC2TerminationRule. - For "Event pattern", select "Custom pattern" and enter:
{ "source": ["aws.ec2"], "detail-type": ["AWS API Call via CloudTrail"], "detail": { "eventSource": ["ec2.amazonaws.com"], "eventName": ["TerminateInstances"] } }- For "Target(s)", select "Event bus" and choose
MyCrossAccountBusagain. This sends the matched event to the custom bus.
- In EventBridge console in
Account-B (Target Account):
-
Create a Lambda Function: This function will be triggered by the events from
Account-A.aws lambda create-function \ --function-name RecordTermination \ --runtime python3.9 \ --zip-file fileb://lambda_handler.zip \ --handler lambda_handler.lambda_handler \ --role arn:aws:iam::ACCOUNT_B_ID:role/LambdaExecutionRole \ --region us-east-1(
lambda_handler.zipcontains your Python code, andLambdaExecutionRoleis an IAM role with permissions to write to your database and CloudWatch Logs). -
Create an EventBridge Event Bus: You’ll need a custom bus in
Account-Bto receive events fromAccount-A.aws events create-event-bus --name MyCrossAccountBus --region us-east-1 -
Create a PutEvents Policy on the Bus (in Account-B): This policy grants
Account-Apermission to put events ontoMyCrossAccountBusinAccount-B.- Go to the EventBridge console in
Account-B. - Select
MyCrossAccountBus. - Go to the "Permissions" tab.
- Click "Create policy".
- Use the following JSON, replacing
ACCOUNT_A_IDwith the actual AWS account ID ofAccount-A:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowAccountAToPutEvents", "Effect": "Allow", "Principal": { "AWS": "ACCOUNT_A_ID" }, "Action": "events:PutEvents", "Resource": "arn:aws:events:us-east-1:ACCOUNT_B_ID:event-bus/MyCrossAccountBus" } ] } - Go to the EventBridge console in
-
Create a Rule to Receive Events and Trigger Lambda: This rule on
MyCrossAccountBusinAccount-Bwill match events fromAccount-Aand send them to theRecordTerminationLambda function.- In EventBridge console in
Account-B, selectMyCrossAccountBus. - Click "Create rule".
- Name it
ReceiveEC2Terminations. - For "Event pattern", select "Custom pattern" and enter:
{ "source": ["aws.ec2"], "detail-type": ["AWS API Call via CloudTrail"], "detail": { "eventSource": ["ec2.amazonaws.com"], "eventName": ["TerminateInstances"] } }- For "Target(s)", select "AWS service" and choose "Lambda function".
- Select your
RecordTerminationLambda function.
- In EventBridge console in
How it works:
When an EC2 instance terminates in Account-A, CloudTrail logs this TerminateInstances API call. The EC2TerminationRule in Account-A matches this event, and because its target is MyCrossAccountBus (also in Account-A), the event is placed onto that bus. The PutEvents policy on MyCrossAccountBus in Account-A allows Account-B to receive events from this bus. The PutEvents policy on MyCrossAccountBus in Account-B allows Account-A to send events to it. The ReceiveEC2Terminations rule in Account-B matches the incoming event from Account-A’s bus and triggers the RecordTermination Lambda function.
The most surprising aspect of this cross-account setup is that the "event bus" itself doesn’t inherently route events between accounts. Instead, you’re granting explicit events:PutEvents permissions from one account to another, allowing the source account to send events to a custom bus in the target account. The target account then uses its own EventBridge rules to process these incoming events.
The next step is often to secure this communication further using AWS Organizations Service Control Policies (SCPs) or by implementing more granular IAM policies on the principals involved.