Chaining Lambda Functions using the Serverless Framework — Part 1
In this article I want to show how to chain AWS Lambda Functions which basically means calling a Lambda Function from another Lambda Function using the Serverless Framework.
TL;DR
Here you can find a GitHub repository if you want a quick start.
Prerequisites
At least for the prerequisites you should check my previous article.
Create Lambda Function
Now we are good to go, so lets create a new project using the Serverless Framework
Bootstrap Project
First create a project
serverless create --template aws-nodejs --path lambda-chaining
Move to the generated project and a dependency to the aws-sdk module
npm install --save aws-sdk
Prepare Environment
The Serverless Framework allows to set AWS IAM access rights, which we are going to need in order to grant rights for invoking a Lambda Function from another Lambda Function. Paste the following in your serverless.yml
service: lambda-chaining
provider:
name: aws
runtime: nodejs6.10
iamRoleStatements:
- Effect: Allow
Action:
- lambda:InvokeFunction
- lambda:InvokeAsync
Resource: "*"
Define Lambda Functions
Finally we can define two Lambda Functions, therefore we create the following functions in the handler.js
'use strict'
var aws = require('aws-sdk')
module.exports.hello = (event, context, callback) => {
var lambda = new aws.Lambda()
var opts = {
FunctionName: 'lambda-chaining-dev-ciao'
}
lambda.invoke(opts, function (err, data) {
if (err) {
console.log('error : ' + err)
callback(err, null)
} else if (data) {
const response = {
statusCode: 200,
body: JSON.parse(data.Payload)
}
callback(null, response)
}
})
}
module.exports.ciao = (event, context, callback) => {
callback(null, { message: 'ciao world!' })
}
For invoking another Lambda Function we have to just specify the name of the Lambda Function which should be invoked. The scheme is the following: service-stage-function. You can see that in line 7 of the handler.js file.
Define handler
One step is left and that is to connect our functions to the respective Lambda Function handlers in the serverless.yml
functions:
hello:
handler: handler.hello
ciao:
handler: handler.ciao
Deploy Lambda Functions
At this point we could deploy our Lambda Functions
serverless deploy -v
You should see verbose output and if everything went fine you can see your Lambda Functions in the respective AWS console view. Just be sure to select the right region.
Invoke Lambda Function
Now you can invoke our first Lambda Function which should call the second one and return the following string “ciao world!”
serverless invoke -f hello -l
Next Steps
Congratulations, you have successfully created, deployed and invoked a Lambda Function which calls another Lambda Function. A next step could be to invoke a Step Function out of Lambda Function which is quite similar to invoking a Lambda Function out of another one. Instead of using
...
var lambda = new aws.Lambda()
var opts = {
FunctionName: 'lambda-chaining-dev-ciao'
}
lambda.invoke(opts, function (err, data) {
...
You would have to use something like
...
var stepfunctions = new aws.StepFunctions()
var params = {
stateMachineArn: <step_function_arn>,
input: JSON.stringify({})
}
stepfunctions.startExecution(params, function (err, data) {
...
One use case for this setup could be if you want to invoke a step function through an AWS API Gateway and want validate your requests against the API Gateway. Validation then would be done in the “Proxy” Lambda which then Invokes the Step Function.
Note that this time we cannot just specify the the name of the Step Function like it was the case for invoking the Lambda. Getting the ARN of the Step Function is not that easy, you can read about it in my dedicated article about referencing Lambda or Step Functions, or having a look at the following GitHub repository if you want to directly walk through code.
Another next step could be to decouple the invocation by using a Message Queue instead of invoking it directly.
Cheers
Noah