This site runs best with JavaScript enabled.

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

  1. Create a service using Serverless framework
  2. Create a SNS topic in resources section of serverless.yml
  3. Create lambda functions - which acts as 'Subscription 1' and 'Subscription 2'
  4. 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.

  1. 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-sns
frameworkVersion: '1'
provider:
name: aws
runtime: nodejs12.x
functions:
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 -y
npm 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.

  1. 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::Topic
Properties:
TopicName: MySNSTopic
  1. 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.handler
events:
- sns:
arn: !Ref MySNSTopicResource
topicName: MySNSTopic
subscription2:
handler: src/handlers/subscription2.handler
events:
- sns:
arn: !Ref MySNSTopicResource
topicName: MySNSTopic

The 'arn' node refers to the resource(SNS Topic) created earlier.

Below is the complete serverless.yml for your reference

service: lambda-sns
frameworkVersion: '1'
provider:
name: aws
runtime: nodejs12.x
plugins:
- serverless-bundle
functions:
subscription1:
handler: src/handlers/subscription1.handler
events:
- sns:
arn: !Ref MySNSTopicResource
topicName: MySNSTopic
subscription2:
handler: src/handlers/subscription2.handler
events:
- sns:
arn: !Ref MySNSTopicResource
topicName: MySNSTopic
resources:
Resources:
MySNSTopicResource:
Type: AWS::SNS::Topic
Properties:
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

Cloud Formation

Click on the SNS topic resource and you'll see something like below

SNS Topic

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

Share article

Join the Newsletter



Mugilan Ragupathi © 2020