简体   繁体   English

AWS Lambda无法在没有VPC的情况下调用另一个AWS Lambda-NodeJs

[英]AWS Lambda unable to invoke another AWS Lambda with No VPC - NodeJs

I have Two AWS Lambda functions, Function A and Function B, 我有两个AWS Lambda函数,函数A和函数B,
Both the Lambda Functions are in No VPC, as none of them require any VPC resources. 两个Lambda函数都在No VPC中,因为它们都不要求任何VPC资源。
Both Lambda functions have LambdaFull Access Role attached. 两个Lambda函数都附加了LambdaFull访问角色。

I am able to Call and Execute Lambda B from Local, 我可以从本地调用并执行Lambda B,
But unable to Call, nor Execute Lambda B from Lambda A. 但是无法调用,也无法从Lambda A执行LambdaB。

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 - 以下是本地代码和Lambda代码-

1. Local - 1.本地-

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 - 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 - 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 - IAM Lambda完全访问策略-

{
    "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 “调用Lambda ...”是我在执行函数时获得的最后一条日志

I found some similar case but, still unable to figure out the issue - 我发现了类似的情况,但仍然无法解决问题-
1. AWS lambda invoke not calling another lambda function - Node.js 1. AWS lambda调用不调用另一个lambda函数-Node.js
2. Nodejs - Invoke an AWS.Lambda function from within another lambda function 2. Node.js-从另一个Lambda函数中调用AWS.Lambda函数
3. invoke aws lambda from another lambda asynchronously 3. 从另一个lambda异步调用aws lambda

The problem is that you have an asynchronous lambda, but you are returning a synchronous function with a callback. 问题是您有一个异步lambda,但是您正在返回带有回调的同步函数。

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). 这意味着当AWS调用Lambda A时,它将等待调用client.invoke() ,该客户端将立即返回(您的回调将在以后的事件中被调用)。 That causes Lambda A to finish and AWS to stop executing. 这导致Lambda A完成并且AWS停止执行。

When you run locally Node actually continues to execute until it has completed all its callbacks, which is why this is succeeding locally. 在本地运行时,Node实际上会继续执行,直到它完成所有回调为止,这就是为什么在本地成功执行的原因。

To get it to work you should return an awaitable, for example in Lambda A: 为了使其正常工作,您应该返回一个等待的结果,例如在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;
 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM