Tutorial: Using Amazon Lambda with Amazon Simple Notification Service
In this tutorial, you use a Lambda function in one Amazon Web Services account to subscribe to an Amazon Simple Notification Service (Amazon SNS) topic in a separate Amazon Web Services account. When you publish messages to your Amazon SNS topic, your Lambda function reads the contents of the message and outputs it to Amazon CloudWatch Logs. To complete this tutorial, you use the Amazon Command Line Interface (Amazon CLI).
To complete this tutorial, you perform the following steps:
-
In account A, create an Amazon SNS topic.
-
In account B, create a Lambda function that will read messages from the topic.
-
In account B, create a subscription to the topic.
-
Publish messages to the Amazon SNS topic in account A and confirm that the Lambda function in account B outputs them to CloudWatch Logs.
By completing these steps, you will learn how to configure an Amazon SNS topic to invoke a Lambda function. You will also learn how to create an Amazon Identity and Access Management (IAM) policy that gives permission for a resource in another Amazon Web Services account to invoke Lambda.
In the tutorial, you use two separate Amazon Web Services accounts. The Amazon CLI commands illustrate this by using two named profiles called accountA
and accountB
, each configured for use with a different Amazon Web Services account. To learn how to configure the Amazon CLI to use different profiles,
see Configuration and credential file settings in the
Amazon Command Line Interface User Guide for Version 2. Be sure to configure the same default Amazon Web Services Region for both profiles.
If the Amazon CLI profiles you create for the two Amazon Web Services accounts use different names, or if you use the default profile and one named profile, modify the Amazon CLI commands in the following steps as needed.
Prerequisites
If you do not have an Amazon Web Services account, use the following procedure to create one.
To sign up for Amazon Web Services
Open http://www.amazonaws.cn/
and choose Sign Up. Follow the on-screen instructions.
Amazon sends you a confirmation email after the sign-up process is
complete. At any time, you can view your current account activity and manage your account by
going to http://www.amazonaws.cn/
After you sign up for an Amazon Web Services account, safeguard your administrative user by turning on multi-factor authentication (MFA). For instructions, see Enable a virtual MFA device for an IAM user (console) in the IAM User Guide.
To give other users access to your Amazon Web Services account resources, create IAM users. To secure your IAM users, turn on MFA and only give the IAM users the permissions needed to perform their tasks.
For more information about creating and securing IAM users, see the following topics in the IAM User Guide:
If you have not yet installed the Amazon Command Line Interface, follow the steps at Installing or updating the latest version of the Amazon CLI to install it.
The tutorial requires a command line terminal or shell to run commands. In Linux and macOS, use your preferred shell and package manager.
Note
In Windows, some Bash CLI commands that you commonly use with Lambda (such as zip
) are not supported by the operating system's built-in terminals.
To get a Windows-integrated version of Ubuntu and Bash, install the Windows Subsystem for Linux
Create an Amazon SNS topic (account A)
To create the topic
-
In account A, create an Amazon SNS standard topic using the following Amazon CLI command.
aws sns create-topic --name sns-topic-for-lambda --profile accountA
You should see output similar to the following.
{ "TopicArn": "arn:aws:sns:us-west-2:123456789012:sns-topic-for-lambda" }
Make a note of the Amazon Resource Name (ARN) of your topic. You’ll need it later in the tutorial when you add permissions to your Lambda function to subscribe to the topic.
Create a function execution role (account B)
An execution role is an IAM role that grants a Lambda function permission to access Amazon Web Services services and resources. Before you create your function in account B, you create a role that gives the function basic permissions to write logs to CloudWatch Logs. We’ll add the permissions to read from your Amazon SNS topic in a later step.
To create an execution role
-
In account B open the roles page
in the IAM console. -
Choose Create role.
-
For Trusted entity type, choose Amazon service.
-
For Use case, choose Lambda.
-
Choose Next.
-
Add a basic permissions policy to the role by doing the following:
-
In the Permissions policies search box, enter
AWSLambdaBasicExecutionRole
. -
Choose Next.
-
-
Finalize the role creation by doing the following:
-
Under Role details, enter
lambda-sns-role
for Role name. -
Choose Create role.
-
Create a Lambda function (account B)
Create a Lambda function that processes your Amazon SNS messages. The function code logs the message contents of each record to Amazon CloudWatch Logs.
This tutorial uses the Node.js 18.x runtime, but we've also provided example code in other runtime languages. You can select the tab in the following box to see code for the runtime you're interested in. The JavaScript code you'll use in this step is in the first example shown in the JavaScript tab.
To create the function
-
Create a directory for the project, and then switch to that directory.
mkdir sns-tutorial cd sns-tutorial
-
Copy the sample JavaScript code into a new file named
index.js
. -
Create a deployment package using the following
zip
command.zip function.zip index.js
-
Run the following Amazon CLI command to create your Lambda function in account B.
aws lambda create-function --function-name Function-With-SNS \ --zip-file fileb://function.zip --handler index.handler --runtime nodejs18.x \ --role arn:aws:iam::
<AccountB_ID>
:role/lambda-sns-role \ --timeout 60 --profile accountBYou should see output similar to the following.
{ "FunctionName": "Function-With-SNS", "FunctionArn": "arn:aws:lambda:us-west-2:123456789012:function:Function-With-SNS", "Runtime": "nodejs18.x", "Role": "arn:aws:iam::123456789012:role/lambda_basic_role", "Handler": "index.handler", ... "RuntimeVersionConfig": { "RuntimeVersionArn": "arn:aws:lambda:us-west-2::runtime:7d5f06b69c951da8a48b926ce280a9daf2e8bb1a74fc4a2672580c787d608206" } }
-
Record the Amazon Resource Name (ARN) of your function. You’ll need it later in the tutorial when you add permissions to allow Amazon SNS to invoke your function.
Add permissions to function (account B)
For Amazon SNS to invoke your function, you need to grant it permission in a statement on a resource-based policy.
You add this statement using the Amazon CLI add-permission
command.
To grant Amazon SNS permission to invoke your function
-
In account B, run the following Amazon CLI command using the ARN for your Amazon SNS topic you recorded earlier.
aws lambda add-permission --function-name Function-With-SNS \ --source-arn arn:aws:sns:
us-east-1:<AccountA_ID>
:sns-topic-for-lambda \ --statement-id function-with-sns --action "lambda:InvokeFunction" \ --principal sns.amazonaws.com --profile accountBYou should see output similar to the following.
{ "Statement": "{\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\": \"arn:aws:sns:us-east-1:<AccountA_ID>:sns-topic-for-lambda\"}}, \"Action\":[\"lambda:InvokeFunction\"], \"Resource\":\"arn:aws:lambda:us-east-1:<AccountB_ID>:function:Function-With-SNS\", \"Effect\":\"Allow\",\"Principal\":{\"Service\":\"sns.amazonaws.com\"}, \"Sid\":\"function-with-sns\"}" }
Note
If the account with the Amazon SNS topic is hosted in an opt-in Amazon Web Services Region,
you need to specify the region in the principal. For example, if you're working with an Amazon SNS topic in the Asia Pacific (Hong Kong) region,
you need to specify sns.ap-east-1.amazonaws.com
instead of sns.amazonaws.com
for the principal.
Grant cross-account permission for Amazon SNS subscription (account A)
For your Lambda function in account B to subscribe to the Amazon SNS topic you created in account A,
you need to grant permission for account B to subscribe to your topic. You grant this permission using the
Amazon CLI add-permission
command.
To grant permission for account B to subscribe to the topic
-
In account A, run the following Amazon CLI command. Use the ARN for the Amazon SNS topic you recorded earlier.
aws sns add-permission --label lambda-access --aws-account-id
<AccountB_ID>
\ --topic-arn arn:aws:sns:us-east-1:<AccountA_ID>
:sns-topic-for-lambda \ --action-name Subscribe ListSubscriptionsByTopic --profile accountA
Create a subscription (account B)
In account B, you now subscribe your Lambda function to the Amazon SNS topic you created at the beginning of the
tutorial in account A. When a message is sent to this topic (sns-topic-for-lambda
), Amazon SNS invokes
your Lambda function Function-With-SNS
in account B.
To create a subscription
-
In account B, run the following Amazon CLI command. Use your default region you created your topic in and the ARNs for your topic and Lambda function.
aws sns subscribe --protocol lambda \ --region
us-east-1
\ --topic-arn arn:aws:sns:us-east-1:<AccountA_ID>
:sns-topic-for-lambda \ --notification-endpoint arn:aws:lambda:us-east-1:<AccountB_ID>
:function:Function-With-SNS \ --profile accountBYou should see output similar to the following.
{ "SubscriptionArn": "arn:aws:sns:us-east-1:<AccountA_ID>:sns-topic-for-lambda:5d906xxxx-7c8x-45dx-a9dx-0484e31c98xx" }
Publish messages to topic (account A and account B)
Now that your Lambda function in account B is subscribed to your Amazon SNS topic in account A, it’s time to test your setup by publishing messages to your topic. To confirm that Amazon SNS has invoked your Lambda function, you use CloudWatch Logs to view your function’s output.
To publish a message to your topic and view your function's output
-
Enter
Hello World
into a text file and save it asmessage.txt
. -
From the same directory you saved your text file in, run the following Amazon CLI command in account A. Use the ARN for your own topic.
aws sns publish --message file://message.txt --subject Test \ --topic-arn arn:aws:sns:
us-east-1:<AccountA_ID>
:sns-topic-for-lambda \ --profile accountAThis will return a message ID with a unique identifier, indicating that Amazon SNS has accepted the message. Amazon SNS then attempts to deliver the message to the topic’s subscribers. To confirm that Amazon SNS has invoked your Lambda function, use CloudWatch Logs to view your function’s output:
-
In account B, open the Log groups
page of the Amazon CloudWatch console. -
Choose the log group for your function (
/aws/lambda/Function-With-SNS
). -
Choose the most recent log stream.
-
If your function was correctly invoked, you’ll see output similar to the following showing the contents of the message you published to your topic.
2023-07-31T21:42:51.250Z c1cba6b8-ade9-4380-aa32-d1a225da0e48 INFO Processed message Hello World 2023-07-31T21:42:51.250Z c1cba6b8-ade9-4380-aa32-d1a225da0e48 INFO done
Clean up your resources
You can now delete the resources that you created for this tutorial, unless you want to retain them. By deleting Amazon resources that you're no longer using, you prevent unnecessary charges to your Amazon Web Services account.
In Account A, clean up your Amazon SNS topic.
To delete the Amazon SNS topic
-
Open the Topics page
of the Amazon SNS console. -
Select the topic you created.
-
Choose Delete.
-
Enter
delete me
in the text input field. -
Choose Delete.
In Account B, clean up your execution role, Lambda function, and Amazon SNS subscription.
To delete the execution role
-
Open the Roles page
of the IAM console. -
Select the execution role that you created.
-
Choose Delete.
-
Enter the name of the role in the text input field and choose Delete.
To delete the Lambda function
-
Open the Functions page
of the Lambda console. -
Select the function that you created.
-
Choose Actions, Delete.
-
Type
confirm
in the text input field and choose Delete.
To delete the Amazon SNS subscription
-
Open the Subscriptions page
of the Amazon SNS console. -
Select the subscription you created.
-
Choose Delete, Delete.