Invoking Lambda from SNS
The following pages address social networking.
In the above page, we specified an email address as the subscriber.
This time, we will check how to specify a Lambda function as a subscriber.
Environment
The configuration is generally the same as in the page introduced at the beginning of this article.
Lambda function 2 sends a message to the SNS topic.
In other words, this function acts as a publisher.
The function gets the UNIX time from the current date/time and sends it as a message.
Specify Lambda function 1 as a subscriber to the SNS topic.
This function determines whether the UNIX time passed as a message is even or odd.
CloudFormation template files
The above configuration is built using CloudFormation.
The CloudFormation templates are located at the following URL
https://github.com/awstut-an-r/awstut-fa/blob/main/100/fa-100.yaml
Explanation of key points of the template files
(Reference) Publish to SNS with Lambda function
Resources:
Function2:
Type: AWS::Lambda::Function
Properties:
Architectures:
- !Ref Architecture
Environment:
Variables:
REGION: !Ref AWS::Region
TOPIC: !Ref TopicArn
Code:
ZipFile: |
import boto3
import datetime
import os
import time
topic = os.environ['TOPIC']
region = os.environ['REGION']
client = boto3.client('sns', region_name=region)
def lambda_handler(event, context):
now = datetime.datetime.now()
now_str = now.strftime('%Y-%m-%d %H:%M:%S.%f')
unix_time = str(time.mktime(now.timetuple()))
print(now_str, unix_time)
response = client.publish(
TopicArn=topic,
Subject=now_str,
Message=unix_time
)
print(response)
FunctionName: !Sub "${Prefix}-function-02"
Handler: !Ref Handler
Runtime: !Ref Runtime
Role: !GetAtt FunctionRole2.Arn
FunctionRole2:
Type: AWS::IAM::Role
DeletionPolicy: Delete
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: sts:AssumeRole
Principal:
Service:
- lambda.amazonaws.com
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: SNSPublishPolicy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- sns:Publish
Resource:
- !Ref TopicArn
Code language: YAML (yaml)
Publish messages from Lambda functions to SNS.
For details, please refer to the page mentioned at the beginning of this article.
For more information on how to create a Lambda function in CloudFormation, please refer to the following page.
This time, we will describe the code to be invoked inline.
Specify Lambda function in SNS subscriber
Resources:
Topic:
Type: AWS::SNS::Topic
Properties:
Subscription:
- Endpoint: !Ref FunctionArn1
Protocol: lambda
TopicName: !Ref Prefix
Code language: YAML (yaml)
Set the subscriber with the Subscription property.
In this case, the SNS message will be received by a Lambda function, so specify the ARN of the function in the Endpoint property and “lambda” in the Protocol property.
When a Lambda function is specified as a subscriber, the SNS invokes the function internally.
Therefore, it is necessary to authorize the SNS to invoke the function.
Resources:
SNSPermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !Ref Function1
Action: lambda:InvokeFunction
Principal: sns.amazonaws.com
SourceArn: !Ref Topic
Code language: YAML (yaml)
I set it up with reference to the following official AWS page
Receive SNS messages by Lambda function
Resources:
Function1:
Type: AWS::Lambda::Function
Properties:
Architectures:
- !Ref Architecture
Code:
ZipFile: |
def lambda_handler(event, context):
subject = event['Records'][0]['Sns']['Subject']
message = event['Records'][0]['Sns']['Message']
print(subject, message)
unix_time = int(float(message))
if (unix_time % 2) == 0:
print('{int} is even !'.format(int=unix_time))
else:
print('{int} is odd !'.format(int=unix_time))
FunctionName: !Sub "${Prefix}-function-01"
Handler: !Ref Handler
Runtime: !Ref Runtime
Role: !GetAtt FunctionRole1.Arn
Code language: YAML (yaml)
Messages sent out from SNS are stored in the event object.
This time, the received UNIX time is determined to be even/odd.
Architecting
Using CloudFormation, we will build this environment and check the actual behavior.
Create CloudFormation stacks and check resources in stacks
Create CloudFormation stacks.
For information on how to create stacks and check each stack, please refer to the following page
After checking the resources in each stack, information on the main resources created this time is as follows
- SNS topic: fa-100
- Lambda function 2: fa-100-function-02
- Lambda function 1: fa-100-function-01
Check the created resource from AWS Management Console.
Check the SNS topic.
You can see that the SNS topic has been successfully created.
You can also see that the Lambda function 1 is registered as a subscriber.
Check the Lambda function.
We can see that two functions have also been created successfully.
If we look at function 1, we can also see that invokes from SNS are allowed.
Checking Operation
1st time
Now that we are ready, we invoke Function 2.
From the Test tab of Function 2, click on “Test” to execute it.
You will see that the function has been successfully executed.
You can see that the UNIX time was calculated from the current date and time and that it was sent out as a SNS message.
This time the UNIX time was “1669204672”.
Next, check the log of Function 1.
There is evidence that the function was executed.
This means that the SNS message was published by the publisher function 2, which automatically invoked the subscriber function 1.
As a result of the even/odd determination of UNIX time, “1669204672 is even ! was output.
2nd time
Perform the same operation again.
The following is the execution log of both functions.
This time, a SNS message with UNIX time “1669204701” was sent out by function 2.
Function 1 is automatically executed in response to this and outputs “1669204701 is odd ! is odd !
Summary
We have confirmed how to specify a Lambda function to the SNS subscriber.