0
votes

I have Two AWS Lambda functions, Function A and Function B,
Both the Lambda Functions are in No VPC, as none of them require any VPC resources.
Both Lambda functions have LambdaFull Access Role attached.

I am able to Call and Execute Lambda B from Local,
But unable to Call, nor Execute Lambda B from Lambda A.

I need synchronous behavior -

line 1 ..
line 2, invoke lambda, get a response,
line 3 to use the response from line 2

Following are the Local and Lambda codes -

1. Local -

let AWS = require('aws-sdk');

let client = new AWS.Lambda({
    region: "us-east-1"
});

let payload = {
    "param1": "ABC",
    "param2": 123
};
payload = JSON.stringify(payload);

let params = {
    FunctionName: 'arn:aws:lambda:us-east-1:awsAccoutNumber:function:test2',
    InvocationType: "RequestResponse", 
    Payload: payload
};

console.log('Invoking Lambda ...');

client.invoke(params, function(err, data) {
    console.log('Lambda invoked!');

    if (err){ 
        console.log('Fail Case');
        console.log(err, err.stack);
    }
    else{     
        console.log('Success Case');
        console.log(data.Payload);
    }
});

2. Lambda A -

let AWS = require('aws-sdk');

exports.handler = async (event) => {

  let client = new AWS.Lambda({
      region: "us-east-1"
  });

  let payload = {
      "param1": "ABC",
      "param2": 123
  };
  payload = JSON.stringify(payload);

  let params = {
      FunctionName: 'arn:aws:lambda:us-east-1:awsAccountNumber:function:test2',
      InvocationType: "RequestResponse", 
      Payload: payload
  };

  console.log('Payload => \n', payload);
  console.log('\nParams => \n', params);
  console.log('\nAWS => \n', AWS.Lambda);
  console.log('\nClient => \n', client);

  console.log('Invoking Lambda ...');

  client.invoke(params, function(err, data) {
      console.log('Lambda invoked!');

      if (err){ 
          console.log('Fail Case');
          console.log(err, err.stack);
          return err;
      }
      else{     
          console.log('Success Case');
          console.log(data.Payload);
          return data.Payload;
      }
  });

};

3. Lambda B -

exports.handler = async (event) => {
    console.log("Event => ", event);

    // TODO implement
    const response = {
        statusCode: 200,
        body: JSON.stringify('Hello from Lambda!'),
    };
    return response;
};

IAM Lambda Full access policy -

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "cloudformation:DescribeChangeSet",
                "cloudformation:DescribeStackResources",
                "cloudformation:DescribeStacks",
                "cloudformation:GetTemplate",
                "cloudformation:ListStackResources",
                "cloudwatch:*",
                "cognito-identity:ListIdentityPools",
                "cognito-sync:GetCognitoEvents",
                "cognito-sync:SetCognitoEvents",
                "dynamodb:*",
                "ec2:DescribeSecurityGroups",
                "ec2:DescribeSubnets",
                "ec2:DescribeVpcs",
                "events:*",
                "iam:GetPolicy",
                "iam:GetPolicyVersion",
                "iam:GetRole",
                "iam:GetRolePolicy",
                "iam:ListAttachedRolePolicies",
                "iam:ListRolePolicies",
                "iam:ListRoles",
                "iam:PassRole",
                "iot:AttachPrincipalPolicy",
                "iot:AttachThingPrincipal",
                "iot:CreateKeysAndCertificate",
                "iot:CreatePolicy",
                "iot:CreateThing",
                "iot:CreateTopicRule",
                "iot:DescribeEndpoint",
                "iot:GetTopicRule",
                "iot:ListPolicies",
                "iot:ListThings",
                "iot:ListTopicRules",
                "iot:ReplaceTopicRule",
                "kinesis:DescribeStream",
                "kinesis:ListStreams",
                "kinesis:PutRecord",
                "kms:ListAliases",
                "lambda:*",
                "logs:*",
                "s3:*",
                "sns:ListSubscriptions",
                "sns:ListSubscriptionsByTopic",
                "sns:ListTopics",
                "sns:Publish",
                "sns:Subscribe",
                "sns:Unsubscribe",
                "sqs:ListQueues",
                "sqs:SendMessage",
                "tag:GetResources",
                "xray:PutTelemetryRecords",
                "xray:PutTraceSegments"
            ],
            "Resource": "*"
        }
    ]
}

The logs just go blank after line -

client.invoke(params, function(err, data) {

"Invoking Lambda ..." is the last log I get on the Function execution

I found some similar case but, still unable to figure out the issue -
1. AWS lambda invoke not calling another lambda function - Node.js
2. Nodejs - Invoke an AWS.Lambda function from within another lambda function
3. invoke aws lambda from another lambda asynchronously

1
What do you mean by "unable to Call"? Do you receive an error message? Does the log contain Lambda invoked!? More details, please.John Rotenstein
The logs just go blank on line - client.invoke(params, function(err, data) {, Invoking Lambda ... is the last log I get on the Function execution, Local code works, but on the function, no error, no successAni
Can you include your IAM policy? Your lambda must have permission to invoke the other lambda.thomasmichaelwallace
@thomasmichaelwallace updated the question with IAM Role policy, I the have AWS AWSLambdaFullAccess policy attached to the Lambda Role.Ani
let res = await client.invoke(params).promise(); console.log(res); That's what i did when i faced same issuesultania23

1 Answers

4
votes

The problem is that you have an asynchronous lambda, but you are returning a synchronous function with a callback.

This means that when AWS invokes Lambda A, it awaits calling client.invoke(), which immediately returns (your callback will be called as part of a later event). That causes Lambda A to finish and AWS to stop executing.

When you run locally Node actually continues to execute until it has completed all its callbacks, which is why this is succeeding locally.

To get it to work you should return an awaitable, for example in Lambda A:

 try {
   const data = await client.invoke(params).promise();
   console.log('Lambda invoked!');
   console.log('Success Case');
   console.log(data.Payload);
   return data.Payload;
 } catch (err) {
   console.log('Fail Case');
   console.log(err, err.stack);
   throw err;
 }