Amazon Simple Notification Service (SNS) is a fully managed publish/subscribe (pub/sub) messaging service that enables fast, flexible, and scalable message delivery. With SNS, you can decouple and scale microservices, distributed systems, and serverless applications. It is widely used for sending real-time notifications and enabling communication between different systems or services.
Key Features of Amazon SNS
Delivery Flexibility: Supports multiple delivery protocols, including HTTP/S, email, SMS, mobile push notifications, and integration with other AWS services like Amazon SQS and AWS Lambda.
Easy Integration: Seamlessly integrates with other AWS services, enabling the construction of highly interconnected and event-driven application architectures.
→ See the official documentation: https://docs.aws.amazon.com/sns/latest/dg/welcome.html
Message Filtering: Allows filtering messages based on attributes, ensuring subscribers receive only relevant notifications.
→ Below is an example of a message and a filter that accepts it. See complete documentation at https://docs.aws.amazon.com/sns/latest/dg/example-filter-policies.html.
Fundamental Concepts
a) Topics
A topic is a communication channel where publishers send messages and to which subscribers subscribe to receive those messages. Each topic has a unique name and can have multiple subscribers.
b) Subscribers
Subscribers are endpoints that receive messages published to an SNS topic. They can be of different types, such as email addresses, phone numbers (SMS), HTTP/S URLs, Amazon SQS queues, or AWS Lambda functions.
c) Publishers
Publishers are entities that send messages to SNS topics. They can be applications, AWS services, or any systems capable of making calls to the SNS API to publish messages.
d) Messages
Messages are the data content sent by publishers to topics and delivered to subscribers. They can contain text or structured data in formats like JSON.
→ Let's look at these concepts in the architecture diagram below:
https://aws.amazon.com/blogs/architecture/get-started-with-amazon-s3-event-driven-design-patterns/
In the diagram, the SNS image represents our topic. The SQS queues are the subscribers, and the S3 bucket is our publisher. The message leaves S3 and becomes available in the topic for subscribers to access.
Getting Started with Amazon SNS
Prerequisites
Access to the AWS Management Console.
Need to send notifications or messages between systems.
Step 1: Create a Topic
Using the AWS Console
Log in to the AWS Management Console.
At the top of the page, use the search bar to find SNS and select Simple Notification Service from the results.
On the Amazon SNS page, in the left panel, click on Topics.
Click Create topic.
→ Path: Amazon SNS > Topics > Create topic
Choose the topic type:
Standard: Best-effort message delivery with unlimited throughput.
FIFO (First-In-First-Out): Guarantees message ordering and exactly-once delivery (ideal for applications requiring ordered processing).
For this example, select Standard.
In Topic name, enter a name, for example,
my-example-topic
.Optionally, configure other properties like encryption, tags, and access policies.
Click Create topic.
Step 2: Subscribe to a Topic
After creating the topic, you'll be directed to the topic details page.
Click Create subscription.
Fill in the following details:
Protocol: Select the delivery protocol (e.g.,
Email
,SMS
,Lambda
,HTTP/S
,Amazon SQS
).Endpoint: Enter the endpoint corresponding to the selected protocol (e.g., the ARN of the SQS queue we created in the previous tutorial).
For this example, select Amazon SQS as the protocol and enter your queue's ARN.
Click Create subscription.
Step 3: Trigger a Message to SNS via Lambda
To publish a message to the SNS topic using a Lambda function, follow these steps:
Create or update your Lambda function:
Access the AWS Lambda console.
Create a new function or edit an existing one.
Add the code to publish to SNS:
Copy and paste the following code into your Lambda function:
import os import boto3 from botocore.exceptions import ClientError # Initialize the SNS client sns_client = boto3.client('sns') def lambda_handler(event, context): # Get the SNS topic ARN from environment variables topic_arn = os.getenv('SNS_TOPIC_ARN') # Message to be published message = "Message triggered via Lambda to SNS!" try: # Publish the message to the SNS topic response = sns_client.publish( TopicArn=topic_arn, Message=message ) print(f"Message published successfully. Message ID: {response['MessageId']}") return { 'statusCode': 200, 'body': f"Message sent to SNS topic successfully! ID: {response['MessageId']}" } except ClientError as e: print(f"Error publishing message to SNS: {e}") return { 'statusCode': 500, 'body': f"Error sending message: {e}" }
Configure the environment variable:
Add the environment variable
SNS_TOPIC_ARN
with the ARN of the SNS topic where the message will be sent.- Example:
arn:aws:sns:us-east-1:123456789012:MyTopic
.
- Example:
Create an IAM Role for your Lambda to publish a message to SNS:
It will look similar to this:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sns:Publish", "Resource": "arn:aws:sns:us-east-1:123456789012:MyTopic" } ] }
Test the message trigger:
Access the Test tab in the Lambda console.
Create a test event (the event can be generic, the Lambda doesn't depend on it in this example).
Execute the function and observe the logs in the console output.
Verify message receipt:
- The subscriber configured in the SNS topic (for example, an email) should receive the message "Message triggered via Lambda to SNS!".
Step 4: How Does Our Final Architecture Look?
Let's remember that we've reached this point now, after gradually adding new services to our design.
Shall we test it? In my account, I created just two queues, two Lambda functions, and one SNS topic. This design with more services is just illustrative that we can grow the solution.
Let's go... first, triggering an event via Lambda:
Let's use the message ID to search for logs in other services:
→ c9d5bfb9-7109-53c5-ab31-e00f7767ab25
Now, did our message reach our queues?
→ Let's see an interesting situation to understand the concepts we've worked with here. My first queue (MyTestQueue) had the Lambda function listening to queue events, so it was emptied of messages. The second queue has no service listening to its events, so it stores the message until we configure that:
-
Done, we have the message in our Lambda function receiving events from SQS with the same ID that was recorded in the message publication via Lambda (c9d5bfb9-7109-53c5-ab31-e00f7767ab25):
Additional Concepts
Message Filtering by Attributes
SNS allows configuring filters so subscribers receive only messages with specific attributes.
When creating or editing a subscription, you can add a filter policy.
Define the attributes and values that the message must contain to be delivered to the subscriber.
Integration with Other AWS Services
Amazon SQS: Send messages to SQS queues for asynchronous processing.
AWS Lambda: Trigger Lambda functions in response to published messages.
Amazon Kinesis Data Firehose: Send data to analytics and storage services.
Security and Access Control
Use topic policies to control who can publish or subscribe to a topic.
Integrate with AWS IAM to manage user and service permissions.
Enable HTTPS to ensure in-transit message encryption.
Final Considerations
Amazon SNS is a powerful tool for building highly scalable and decoupled systems. Understanding the concepts of topics, subscriptions, publishers, and messages is fundamental to using SNS effectively. Using the AWS Management Console, you can quickly set up the messaging infrastructure needed for your applications.