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):

  1. 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-1
    

    This creates a bus named MyCrossAccountBus in us-east-1.

  2. Create a PutEvents Policy on the Bus: This policy grants Account-B permission to put events onto MyCrossAccountBus in Account-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_ID with the actual AWS account ID of Account-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"
            }
        ]
    }
    
  3. 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, select MyCrossAccountBus.
    • 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 MyCrossAccountBus again. This sends the matched event to the custom bus.

Account-B (Target Account):

  1. 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.zip contains your Python code, and LambdaExecutionRole is an IAM role with permissions to write to your database and CloudWatch Logs).

  2. Create an EventBridge Event Bus: You’ll need a custom bus in Account-B to receive events from Account-A.

    aws events create-event-bus --name MyCrossAccountBus --region us-east-1
    
  3. Create a PutEvents Policy on the Bus (in Account-B): This policy grants Account-A permission to put events onto MyCrossAccountBus in Account-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_ID with the actual AWS account ID of Account-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"
            }
        ]
    }
    
  4. Create a Rule to Receive Events and Trigger Lambda: This rule on MyCrossAccountBus in Account-B will match events from Account-A and send them to the RecordTermination Lambda function.

    • In EventBridge console in Account-B, select MyCrossAccountBus.
    • 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 RecordTermination Lambda function.

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.

Want structured learning?

Take the full Eventbridge course →