Send SNS Notification from AWS Lambda using Python Boto3

Send SNS Notification from AWS Lambda using Python Boto3

Send SNS Notification from AWS Lambda using Python Boto3

Serverless applications are the new normal nowadays. AWS has an amazing service AWS Lambda that’s the backbone of serverless at AWS. While developing your serverless application, it’s quite common to publish a message/notification to an SNS topic from your lambda function.

In this post, you’ll learn to send SNS notifications from AWS Lambda using python boto3. e will do it step by step including permissions settings for your lambda function. So stay tuned.

So, are you excited?

Don’t want to miss any posts from us? join us on our Facebook group, and follow us on Facebook, Twitter, LinkedIn, and Instagram. You can also subscribe to our newsletter below to not miss any updates from us.

Prerequisite

How to Send SNS Notification from AWS Lambda using Python Boto3

  1. Create an SNS Topic
  2. Create a Lambda Function
  3. Write Code to Publish Notification to SNS
  4. Provide Lambda Permission to Publish to SNS
  5. Test the Lambda function

Step 1: Create an SNS Topic

If you already have an SNS topic, keep the topic ARN handy and move to the next step.

Or else stay with me as we create an SNS topic for this demo that we’ll use to publish a notification.

Alright !!

Login to AWS Management Console and navigate to the SNS service.

Click Create topic

Send SNS Notification from AWS Lambda using Python Boto3

Enter a topic name and click the Next step

For type, go with Standard right now as we don’t have the need for a FIFO topic.

Leave everything as default and click Create topic.

Once the topic is successfully created, you are navigated to the details screen. Grab the topic ARN from the screen. You can see where it is shown in the details screen-

Send SNS Notification from AWS Lambda using Python Boto3 2

SNS Topic ARN: arn:aws:sns:ap-south-1:123456789012:DemoTopic

We have noted the SNS Topic ARN now so let’s start with lambda creation.

Step 2: Create a Lambda Function

Navigate to Lambda service and click Create function

Choose the option Author from scratch

Fill up details like

  • Function name: Demo_Function (You can put anything you want)
  • Runtime: Python 3.9 (Choosing Python’s latest version for python lambda)
  • Architecture: Leave it as default x86_64. You can also choose arm64 if you want to make use of the Graviton2 processor

This is what it looks like-

Send SNS Notification from AWS Lambda using Python Boto3 3

Leave the rest of the things as default as we can change things later. Scroll down and click Create function.

You will get a success message like below-

Step 3: Write Code to Publish Notification to SNS

A lambda with a basic execution role gets created. Before we write the code, let me tell you that we use the boto3 library, AWS SDK for Python. There are mainly two ways in which we interact with AWS service via boto3. It is Client and Resource. Today we will be using the client’s publish method to publish an SNS notification.

This is what it looks like-

response = client.publish(
    TopicArn='string',
    TargetArn='string',
    PhoneNumber='string',
    Message='string',
    Subject='string',
    MessageStructure='string',
    MessageAttributes={
        'string': {
            'DataType': 'string',
            'StringValue': 'string',
            'BinaryValue': b'bytes'
        }
    },
    MessageDeduplicationId='string',
    MessageGroupId='string'
)

You can read more above client.publish() on official documentation.

Time to write the code.

demo_lambda.py

import json
import boto3

# Initialize the SNS client object outside of the handler
sns = boto3.client('sns')

def lambda_handler(event, context):
    try:
        # Publish a message to the the Demo_Topic
        topic_arn = 'arn:aws:sns:ap-south-1:123456789012:DemoTopic'
        message = 'Hello and Welcome to CloudKatha!'
        
        response = sns.publish(
            TopicArn=topic_arn,
            Message= message
        )
        
        print('Message published to SNS topic')
        return {
            'statusCode': 200,
            'body': json.dumps(response)
        }
    except Exception as e:
        print('Failed to publish message to SNS topic')
        return {'status': 'error', 'message': str(e)}

Code explanation-

1. Import Libraries

import json
import boto3

First and foremost, we have imported the necessary libraries that we need in our program.

2. Create SNS Client


# Initialize the SNS client object outside of the handler
sns = boto3.client('sns')

Next, we create an SNS client using Boto3. Making the client outside handler is recommended and results in performance improvement.

3. Publish to SNS

# Publish a message to the the Demo_Topic
topic_arn = 'arn:aws:sns:ap-south-1:123456789012:DemoTopic'
message = 'Hello and Welcome to CloudKatha!'
        
response = sns.publish(
   TopicArn=topic_arn,
   Message= message
)

Next, we initialize topic_arn and a message that we want to send. And finally, we call sns.publish() method passing the topic ARN and message.

4. Return the Response

return {
   'statusCode': 200,
   'body': json.dumps(response)
}

Finally, we are returning a response containing statusCode 200 indicating success and also the response that we got back from SNS publish.

Note: You will need to replace the SNS topic ARN with the ARN of your own SNS topic in the code.

Code wise we are done.

However, If you test your lambda function now, you will get errors like-

{
“status”: “error”,
“message”: “An error occurred (AuthorizationError) when calling the Publish operation: User: arn:aws:sts::123456789012:assumed-role/Demo_Lambda-role-xrvgcllr/Demo_Lambda is not authorized to perform: SNS:Publish on resource: arn:aws:sns:ap-south-1:123456789012:DemoTopic because no identity-based policy allows the SNS:Publish action”
}

And it is so very obvious.

AWS Lambda can only perform things that are allowed in the role attached to it. The default role does not have access to the AWS SNS service.

So let’s modify the lambda role and provide access to SNS publish action.

Step 4: Provide Lambda Permission to Publish to SNS

Navigate to the Configuration tab in the lambda console. Click on Permissions from the left nav menu as shown below and click on the Execution role.

Send SNS Notification from AWS Lambda using Python Boto3 5

Once you click on the role, you are navigated to IAM. In the permission section,

Send SNS Notification from AWS Lambda using Python Boto3 6

Click on Create inline policy

Navigate to json tab and paste the below policy.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "SNS",
            "Effect": "Allow",
            "Action": "sns:Publish",
            "Resource": "arn:aws:sns:ap-south-1:123456789012:DemoTopic"
        }
    ]
}

Don’t forget the change the SNS topic ARN in the resource with your own topic ARN.

Click Review policy

In the review screen, provide the name of the policy-

Name: SNS_Access_Policy

Click Create policy

And that’s it, You will see that the created policy is attached to the lambda role. You can see the below screenshot.

Step 5: Test the Lambda function

Time to test our lambda function. Before that don’t forget to click on Deploy to deploy changes that you made in the console for your lambda function. Every time you make a change, you need to deploy it. Don’t worry, the console will indicate to you that you need to deploy your changes.

Click on Test

Configure test event

Provide an event name.

Leave the JSON as it is as well are not using it anyway.

Click Save

Click Test once more

And Voila !!!

The message is sent successfully and we see the response as expected.

Send SNS Notification from AWS Lambda using Python Boto3 7

Bonus Tip

In this example, we saw how to send a hello world notification to SNS using AWS Lambda in Python and Botot3.

There are times when you want to send different messages for different protocols such as email, HTTP or SMS etc.

For that, you have to set If you set MessageStructure to json

In this case, the message param must be a valid JSON. Additionally, it must also contain a default string message for SNS to fall back to.

This is how the resulting code will look like-

import json
import boto3

# Initialize the SNS client object outside of the handler
sns = boto3.client('sns')

def lambda_handler(event, context):
    try:
        # Publish a message to the the Demo_Topic
        topic_arn = 'arn:aws:sns:ap-south-1:123456789012:DemoTopic'
        message = {
            'default': json.dumps({'message': 'Hello World !!!'}),
            'email': json.dumps({
                'subject': 'Test Message',
                'message': 'Message for Email Protocol'
            })
        }
        
        response = sns.publish(
            TopicArn=topic_arn,
            Message=json.dumps({'default': message}),
            MessageStructure='json'
        )
        
        print('Message published to SNS topic')
        return {
            'statusCode': 200,
            'body': json.dumps(response)
   }
    except Exception as e:
        print('Failed to publish message to SNS topic')
        return {'status': 'error', 'message': str(e)}

Conclusion

In this tutorial, you learnt how to send SNS notification from AWS Lambda using Python Boto3.

Firstly, we created an SNS topic. Secondly, we created a lambda function in the AWs console using Python. Thirdly we wrote the code to send notifications to SNS and also provided lambda role permission to publish on our SNS topic.

Finally, we tested to see how things work together and verified the lambda response from SNS publish.

Hope this post was useful to you. If so, don’t forget to tell me in the comment section.

Enjoyed the content?

Subscribe to our newsletter below to get awesome AWS learning materials delivered straight to your inbox.

Don’t forget to motivate me by-

  • Adding a comment below on what you liked and what can be improved.
  • Follow us on Facebook , TwitterLinkedIn and Instagram
  • Share this post with your friends

Suggested Read:

Leave a Reply

Your email address will not be published. Required fields are marked *