Integrating AWS Lambda with SNS using Serverless Framework - NodeJS version
Mugilan Ragupathi
—October 01, 2020
AWS SNS (Simple Notification Service) enables you to communicate between systems through publish/subscribe pattern.
Consider below system architecture diagram.
'System A' acts as a 'Publisher' in the above system. It creates messages and publishes those messages to a SNS topic. 'System A' does not care about who consumes these messages. The components who consume these messages are called 'Subscriptions' and these subscriptions do not care about how these messages were created. In the above system diagram, there are couple of subscriptions - 'Subscription 1' and 'Subscription 2'. Both 'System B' and 'System C' would consume the same messages via 'Subscription 1' and 'Subscription 2' but the way those messages getting processed could be different based on their business rules. For example, 'System B' would process these messages whereas 'System C' would just analyze the message and provide analytics.
We're going to implement above system design using serverless framework.
Below are the steps that we need to do
- Create a service using Serverless framework
- Create a SNS topic in resources section of serverless.yml
- Create lambda functions - which acts as 'Subscription 1' and 'Subscription 2'
- Refer the SNS topic as event source for your lambda functions
I hope you know how to create 'hello-world' service in serverless framework. If not, please refer this article.
- Create a service using Serverless framework:
serverless create --template aws-nodejs --path lambda-sns
Once you create new service, your serverless.yml would look something like below
service: lambda-snsframeworkVersion: '1'provider:name: awsruntime: nodejs12.xfunctions:hello:handler: handler.hello
Optionally, you can install 'serverless-bundle' plugin to support ES6 functionality in your lambda code. This plugin node will be at top level (i.e, sibling to provider node)
plugins:- serverless-bundle
npm init -ynpm i -D serverless-bundle
First command 'npm init -y' will create package.json file without asking any questions and the second command will install 'serverless-bundle as your dev dependency.
- Create SNS Topic in resources section of serverless.yml
We need to create a new SNS Topic so that publisher can send messages to this topic. To create any resources in serverless framework, we'll need to use resources section.
resources:Resources:MySNSTopicResource:Type: AWS::SNS::TopicProperties:TopicName: MySNSTopic
- Create lambda functions which act as subscriptions
I've created a folder 'src/handlers' at root level and lambda functions would reside here. Created lambda function - subscription1.js with following code
function systemB(event, context) {console.log('consuming in System B');console.log('event received:', JSON.stringify(event));console.log('context received:', context);return {statusCode: 200,body: JSON.stringify({input: event,}, null, 2),};}export const handler = systemB;
Created another lambda function - subscription2.js with following code
function systemC(event, context) {console.log('consuming in System C');console.log('event received:', JSON.stringify(event));console.log('context received:', context);return {statusCode: 200,body: JSON.stringify({input: event,}, null, 2),};}export const handler = systemC;
If you want to do any processing, you can do so in these lambda functions. But I'm just logging into the console. These logs can be viewed from 'CloudWatch' logs.
4. Refer the SNS topic as event source for your lambda functions
'functions' node reside at root level of serverless.yml file and it has 2 lambda functions - 'subscription1' and 'subscription2', as shown in below code snippet. 'handler' tells where the lambda code is located and 'events' node represents triggering events(sns in this case) for the lambda function.
functions:subscription1:handler: src/handlers/subscription1.handlerevents:- sns:arn: !Ref MySNSTopicResourcetopicName: MySNSTopicsubscription2:handler: src/handlers/subscription2.handlerevents:- sns:arn: !Ref MySNSTopicResourcetopicName: MySNSTopic
The 'arn' node refers to the resource(SNS Topic) created earlier.
Below is the complete serverless.yml for your reference
service: lambda-snsframeworkVersion: '1'provider:name: awsruntime: nodejs12.xplugins:- serverless-bundlefunctions:subscription1:handler: src/handlers/subscription1.handlerevents:- sns:arn: !Ref MySNSTopicResourcetopicName: MySNSTopicsubscription2:handler: src/handlers/subscription2.handlerevents:- sns:arn: !Ref MySNSTopicResourcetopicName: MySNSTopicresources:Resources:MySNSTopicResource:Type: AWS::SNS::TopicProperties:TopicName: MySNSTopic
Deploying the package:
When you execute below command, serverless framework would package and deploy your necessary resources - Lambda functions, SNS, Cloudformation etc...
serverless deploy
Testing functionality:
You can login to aws console and select 'CloudFormation' service. You can see a stack 'lambda-sns-dev' over there. In the resources tab, you can see the list of resources created, as shown in below screenshot
Click on the SNS topic resource and you'll see something like below
As you can see, there are couple of subscriptions to this topic. Please click on 'Publish message' button at top right hand corner of the screen and send some test message.
Once the test message is sent, open 'Cloudwatch logs', you'll be able to see the log messages in both of the subscriptions.
If you like this article, please subscribe to my newsletter below