Nodejs - Invoke an AWS.Lambda function from within another lambda function
Invoking a Lambda Function from within another Lambda function is quite simple using the aws-sdk
which is available in every Lambda.
I suggest starting with something simple first.
This is the "Hello World" of intra-lambda invocation:
Lambda_A
invokes Lambda_B
with a Payload
containing a single parameter name:'Alex'
.Lambda_B
responds with Payload: "Hello Alex"
.
First create Lambda_B
which expects a name
propertyon the event
parameter
and responds to request with "Hello "+event.name
:
Lambda_B
exports.handler = function(event, context) { console.log('Lambda B Received event:', JSON.stringify(event, null, 2)); context.succeed('Hello ' + event.name);};
Ensure that you give Lambda_B
and Lambda_A
the same role.
E.g: create a role called lambdaexecute
which has AWSLambdaRole
, AWSLambdaExecute
andAWSLambdaBasicExecutionRole
(All are required):
Lambda_A
var AWS = require('aws-sdk');AWS.config.region = 'eu-west-1';var lambda = new AWS.Lambda();exports.handler = function(event, context) { var params = { FunctionName: 'Lambda_B', // the lambda function we are going to invoke InvocationType: 'RequestResponse', LogType: 'Tail', Payload: '{ "name" : "Alex" }' }; lambda.invoke(params, function(err, data) { if (err) { context.fail(err); } else { context.succeed('Lambda_B said '+ data.Payload); } })};
Once you have saved both these Lambda functions, Test run Lambda_A
:
Once you have the basic intra-lambdda invocation working you can easily extend it to invoke more elaborate Lambda functions.
The main thing you have to remember is to set the appropriate
ARN Role
for all functions.
As of Dec 3, 2016, you can simply use an AWS Step function to put Lambda function Lambda_B as the sequential step of Lambda_A.
With AWS Step Functions, you define your application as a state machine, a series of steps that together capture the behavior of the app. States in the state machine may be tasks, sequential steps, parallel steps, branching paths (choice), and/or timers (wait). Tasks are units of work, and this work may be performed by AWS Lambda functions, Amazon EC2 instances of any type, containers, or on premises servers—anything that can communicate with the Step Functions API may be assigned a task.
So the following state machine should meet your need.
Here is the code corresponding to the state machine.
{ "Comment": "A simple example of the Amazon States Language using an AWS Lambda Function", "StartAt": "Lambda_A", "States": { "Lambda_A": { "Type": "Task", "Resource": "arn:aws:lambda:REGION:ACCOUNT_ID:function:FUNCTION_NAME", "Next": "Lambda_B" }, "Lambda_B":{ "Type": "Task", "Resource": "arn:aws:lambda:REGION:ACCOUNT_ID:function:FUNCTION_NAME", "End": true } }}
Moreover, you can add much more sophisticated logics in a state machine, such as parallel steps and catch failures. It even logs the details of every single execution which makes debugging a much better experience, especially for lambda functions.
Everything mentioned by @nelsonic is correct, except for the roles.
I tried choosing the roles that he mentioned above:
- AWSLambdaExecute
- AWSLambdaBasicExecutionRole
But it did not allow me to invoke my other lambda function, so I changed the role to the below:
- AWSLambdaRole
- AWSLambdaBasicExecutionRole
The reason behind is AWSLambdaExecute only provides Put, Get access to S3 and full access to CloudWatch Logs.but AWSLambdaRole provides Default policy for AWS Lambda service role.if you observe its permission policy it will talk about the invokeFunction
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "lambda:InvokeFunction" ], "Resource": [ "*" ] } ]}
Note: it is OK to proceed without AWSLambdaBasicExecutionRole policy as it only enables the logging in the cloud watch nothing much. But AWSLambdaRole is absolutely necessary.