hero-image

Connecting Event Busses Across AWS Accounts

5 Minutes

10/01/2021

I've spent the last few weeks researching how to connect event busses in two different AWS accounts using the CDK. Most of the information that I've found has just been CloudFormation templates, which is fine, but some of the resources you have to create in CloudFormation are automatically created in the CDK.

Now that I've solved the problem, I'd like to help the next unfortunate sole that needs to implement this. Fortunately the final solution isn't that complicated.

This article leaves out some boilerplate code, like creating the stacks. For the full source go to: https://github.com/theBenForce/post-samples/tree/article/cross-account-event-bus

What's needed?

To get this to work you'll have to create a bus in each account—obviously. Beyond that, you'll need to create different resources for the sending and receiving accounts.

In the receiving account you'll need to create the rule that you want to be triggered by the message, and a policy on the target bus that allows messages from the sending account.

In the sending account you'll need to create an IAM Role that allows put events to the receiving bus. You'll also need to create a rule on the sending bus that references that role and forwards events to the receiving bus.

Setting up the target account

First, create the target bus. You'll need to set the name so that the ARN can be used in a stack in another account.

const targetBus = new events.EventBus(this, "TargetBus", {
  eventBusName: "TargetBus"
});

Since we're going to be referencing this bus from another account, we need to tell the CDK to generate a physical name during the synthesis process. This enable the CDK to generate an ARN before deployment.

targetBus._enableCrossEnvironment();

Now you need to create an event bus policy that allows messages from the source account.

new events.CfnEventBusPolicy(this, "CrossAccountPolicy", {
  action: "events:PutEvents",
  eventBusName: targetBus.eventBusName,
  principal: sourceAccountId,
  statementId: `AcceptFrom${sourceAccountId}`,
});

This wouldn't be any fun if you didn't get to see your events somewhere in the target account. To make that happen, create a CloudWatch log group that you can dump all of the received messages into.

const eventLogs = new logs.LogGroup(this, "EventLogs", {
  logGroupName: "EventLogs",
});

Finally, you need to create the rule that you want triggered. The rule will pass all events with a detailType set to TestEvent into the log group that you created.

new events.Rule(this, "TestRule", {
  eventBus: targetBus,
  eventPattern: {
    detailType: ["TestEvent"],
  },
	targets: [
    new eventsTargets.CloudWatchLogGroup(eventLogs),
  ],
});

Setting up the source account

Start by creating the bus that will be sending events.

const sourceBus = new events.EventBus(this, "SourceBus");

And create a rule that will forward TestEvent messages to the target bus. The CDK creates both the Event Bus Rule and an IAM Role that will allow your Event Bus to send messages to the target Event Bus.

new events.Rule(this, "TestRule", {
	eventBus: sourceBus,
	eventPattern: "TestEvent",
	targets: [
		new eventsTargets.EventBus(targetBus)
	]
});

Deploy

Now that you've created both busses, go ahead and deploy them. Without any fancy setup, you'll need to deploy the stacks one at a time using the proper AWS profile for each.

npx cdk deploy --profile source SourceStack
npx cdk deploy --profile target TargetStack

Testing

Now that both stacks are deployed you can test the connection. Log into the source account's AWS console and navigate to "Event busses" in the EventBridge service. Select your bus then click Actions→Send events.

Selecting an event bus

On the page that opens, make sure the "Detail type" matches the value you used when you created the event bus rule.

Sending an event

Now head over to your target account and open the CloudWatch log group that you created. You should see your message there.

View event in target

Summary

Connecting event bridges across two AWS accounts requires several pieces to get it working, fortunately the CDK makes it pretty simple to create them. In the target account you need to create an Event Bus with an Event Bus Policy that allows messages from the source account. The source account needs an IAM Role attached to an Event Bus Rule, which the CDK takes care of behind the scenes.