Introduction to Amazon Simple Notification Service (SNS)

Introduction to Amazon Simple Notification Service (SNS)

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

  1. Log in to the AWS Management Console.

  2. At the top of the page, use the search bar to find SNS and select Simple Notification Service from the results.

  3. On the Amazon SNS page, in the left panel, click on Topics.

  4. Click Create topic.

    → Path: Amazon SNS > Topics > Create topic

  5. 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).

  6. For this example, select Standard.

  7. In Topic name, enter a name, for example, my-example-topic.

  8. Optionally, configure other properties like encryption, tags, and access policies.

  9. Click Create topic.

Step 2: Subscribe to a Topic

  1. After creating the topic, you'll be directed to the topic details page.

  2. Click Create subscription.

  3. 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).

  4. For this example, select Amazon SQS as the protocol and enter your queue's ARN.

  5. 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:

  1. Create or update your Lambda function:

    • Access the AWS Lambda console.

    • Create a new function or edit an existing one.

  2. 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}"
                }
      
  3. 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.
  4. 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"
            }
          ]
        }
      
  5. 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.

  6. 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?

  1. Let's remember that we've reached this point now, after gradually adding new services to our design.

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

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

  4. 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:

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

  1. When creating or editing a subscription, you can add a filter policy.

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

Additional Resources

  • Amazon SNS Documentation: Link

  • Amazon SNS Tutorials: Link

  • AWS CLI Command Reference for SNS: Link

  • Integration Examples with AWS Lambda: Link

  • SNS Security Best Practices: Link