serverless.yml中的引用函数

时间:2017-05-17 18:48:00

标签: javascript amazon-web-services aws-lambda serverless-framework amazon-cloudformation

我运行了几个AWS lambda,由无服务器框架支持。我需要一个lambda(称为lambdaOne),它将使用AWS'javascript sdk调用第二个lambda(称为lambdaTwo)。问题是,当我尝试这个时,我得到AccessDenied例外:

  

UnhandledPromiseRejectionWarning:未处理的承诺拒绝(拒绝ID:1):   AccessDeniedException:User:arn:aws:sts :: 12345678909876:assume-role / test-dev-us-west-2-lambdaRole / test-dev-lambdaOne无权执行:lambda:在资源上调用函数:arn:aws :拉姆达:US-西-2:994979977450:功能:测试-DEV-lambdaTwo

根据我的理解,无服务器为所有lambda函数创建function角色。所以,我应该只能在iamRoleStatements下添加一个新条目。

我的困惑源于我想引用的资源(lambdaTwo)已被定义为{{3}}。

有没有办法将function作为资源引用?

2 个答案:

答案 0 :(得分:3)

目前,没有为Lambda函数声明权限的快捷方式。您需要根据其ARN提供权限。

下面是一个工作示例。

<强> serverless.yml

service: test-invoke-function

provider:
  name: aws
  runtime: nodejs6.10
  region: us-east-1
  stage: dev
  environment:
    AWS_ACCOUNT: 1234567890 # use your own AWS ACCOUNT number here

    # define the ARN of the function that you want to invoke
    FUNCTION_ARN: "arn:aws:lambda:${self:provider.region}:${self:provider.environment.AWS_ACCOUNT}:function:${self:service}-${self:provider.stage}-lambdaTwo"  

functions:
  # lambdaOne will invoke lambdaTwo
  lambdaOne: 
    handler: handler.lambdaOne
    role: functionPermission # we'll define later in this file

  lambdaTwo:
    handler: handler.lambdaTwo

# define the IAM permissions of our Lambda function
resources:
  Resources:
    functionPermission:
      Type: AWS::IAM::Role
      Properties:
        RoleName: functionPermission
        AssumeRolePolicyDocument:
          Version: '2012-10-17'
          Statement:
            - Effect: Allow
              Principal:
                Service:
                  - lambda.amazonaws.com
              Action: sts:AssumeRole
        Policies:
          - PolicyName: functionPermission
            PolicyDocument:
              Version: '2012-10-17'
              Statement:
                - Effect: "Allow"
                  Action:
                    - "lambda:InvokeFunction"
                  Resource: "${self:provider.environment.FUNCTION_ARN}"

<强> handler.js

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

module.exports.lambdaOne = (event, context, callback) => {  
  const lambda = new AWS.Lambda();
  const params = {
    FunctionName: process.env.FUNCTION_ARN,
    Payload: JSON.stringify({ message: 'lambdaOne invoking lambdaTwo' })
  };

  // invoke lambdaTwo
  lambda.invoke(params, (err, data) => {
    if (err) {
      callback(err, null);
      return;
    }

    const response = {
      statusCode: 200,
      body: JSON.stringify({
        message: 'lambdaOne result',
        result: data
      })
    };

    callback(null, response);
  });
};

module.exports.lambdaTwo = (event, context, callback) => {  
  const response = {
    statusCode: 200,
    body: JSON.stringify({
      message: 'lambdaTwo result',
      data: event
    })
  };

  callback(null, response);
};

答案 1 :(得分:1)

您还可以使用serverless-iam-roles-per-function插件,该插件允许您为每个lambda函数附加单独的IAM角色,并与serverless-pseudo-parameters结合使用,可以引用另一个lambda。