Amazon EventBridge is a serverless event bus service that makes it easy to connect applications together using data from your own applications, SaaS applications, and AWS services. When you need to send an event to multiple destinations, you typically configure EventBridge to fan out those events. While EventBridge can directly target multiple resources, for high-volume or complex fan-out scenarios, using Amazon SNS as an intermediary is a common and powerful pattern.
Let’s see EventBridge and SNS working together. Imagine we have a UserCreated event published to EventBridge. We want this event to trigger three different actions:
- Send a welcome email to the new user.
- Log the user creation event to a data warehouse.
- Notify a Slack channel about the new user.
Here’s how you’d set that up.
First, create an SNS topic. This topic will act as the fan-out point.
aws sns create-topic --name user-creation-events
This command returns a TopicArn. Let’s say it’s arn:aws:sns:us-east-1:123456789012:user-creation-events.
Next, create subscriptions to this SNS topic for each of your desired destinations. For simplicity, we’ll use SQS queues for the email and data warehouse, and an HTTP endpoint (representing a Lambda function or webhook) for Slack.
Create SQS queues:
aws sqs create-queue --queue-name welcome-email-queue
aws sqs create-queue --queue-name data-warehouse-queue
Get their ARNs. For example:
welcome_email_queue_arn="arn:aws:sqs:us-east-1:123456789012:welcome-email-queue"
data_warehouse_queue_arn="arn:aws:sqs:us-east-1:123456789012:data-warehouse-queue"
Subscribe the SQS queues to the SNS topic:
aws sns subscribe --topic-arn arn:aws:sns:us-east-1:123456789012:user-creation-events --protocol sqs --notification-endpoint $welcome_email_queue_arn
aws sns subscribe --topic-arn arn:aws:sns:us-east-1:123456789012:user-creation-events --protocol sqs --notification-endpoint $data_warehouse_queue_arn
For the Slack notification, you’d typically have a Lambda function that’s subscribed to the SNS topic. Let’s assume you have a Lambda function ARN: slack-notification-lambda-arn="arn:aws:lambda:us-east-1:123456789012:function:SlackNotifier". You need to grant SNS permission to invoke your Lambda function.
aws lambda add-permission \
--function-name SlackNotifier \
--statement-id SNSInvoke \
--action "lambda:InvokeFunction" \
--principal sns.amazonaws.com \
--source-arn arn:aws:sns:us-east-1:123456789012:user-creation-events
Then, subscribe the Lambda function to the SNS topic:
aws sns subscribe --topic-arn arn:aws:sns:us-east-1:123456789012:user-creation-events --protocol lambda --notification-endpoint $slack-notification-lambda-arn
Now, create an EventBridge rule. This rule will match the UserCreated event and send it to the SNS topic.
aws events put-rule \
--name UserCreatedRule \
--event-pattern '{"source": ["com.mycompany.users"], "detail-type": ["UserCreated"]}'
This command returns a RuleArn. Let’s say it’s user_created_rule_arn="arn:aws:events:us-east-1:123456789012:rule/UserCreatedRule".
Finally, add a target to the EventBridge rule, pointing to your SNS topic.
aws events put-targets \
--rule UserCreatedRule \
--targets "Id"="1","Arn"="arn:aws:sns:us-east-1:123456789012:user-creation-events"
When a UserCreated event arrives at EventBridge, the UserCreatedRule will match it. The rule’s target is the SNS topic. SNS then fans out the event to all its subscribers: the two SQS queues and the Lambda function. The Lambda function processes the event and sends a message to Slack. The SQS queues will hold the event for the separate services to process (e.g., a Lambda function processing the welcome email queue).
The most surprising true thing about this pattern is that SNS itself doesn’t guarantee delivery order or exactly-once processing to its subscribers; it offers at-least-once delivery. This means your downstream consumers (like your Lambda functions or services polling SQS) must be designed to be idempotent and handle potential duplicate messages gracefully. If strict ordering or exactly-once delivery is critical, you’d need to add more complexity, perhaps by using EventBridge Pipes with an SQS FIFO queue as a destination, or by building custom deduplication logic.
When a UserCreated event is published to EventBridge, the UserCreatedRule matches it. This rule is configured with a single target: the SNS topic arn:aws:sns:us-east-1:123456789012:user-creation-events. EventBridge sends the event to this SNS topic. SNS then takes over the fan-out responsibility. It asynchronously delivers a copy of the event message to each of its subscribers. In our example, these subscribers are two SQS queues and a Lambda function. The SQS queues are polled by separate services for processing, and the Lambda function is invoked directly by SNS to send a Slack notification. This decoupling allows each downstream process to operate independently and at its own pace, while EventBridge focuses on routing and SNS on distribution.
This pattern is incredibly flexible. You can add or remove subscribers to the SNS topic dynamically without altering the EventBridge rule or the event producer. For instance, if you later decide to send a notification to a PagerDuty service, you simply create a new subscription to the user-creation-events SNS topic for PagerDuty. The original event producer and EventBridge rule remain unchanged. The primary benefit is that EventBridge is a powerful event router, but SNS is purpose-built for fan-out and provides robust delivery mechanisms to various endpoint types, including HTTP/S, email, SMS, SQS, and Lambda.
What most people don’t realize is how SNS handles message attributes. When an event is published to SNS, it can carry both a message body and message attributes. EventBridge, when targeting an SNS topic, can map fields from the event’s JSON payload into SNS message attributes. This is incredibly useful for filtering events at the SNS subscription level. For example, you could configure an SQS subscription to only receive messages where a specific attribute, like user_tier: "premium", is present. This allows for a secondary layer of routing logic directly within SNS, reducing the load on downstream consumers by preventing them from receiving and filtering events they don’t care about.
The next logical step in managing event-driven architectures at scale is exploring EventBridge Pipes for more complex point-to-point integrations or advanced filtering and transformation.