最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Reference function from within serverless.yml - Stack Overflow

programmeradmin1浏览0评论

I have several AWS lambdas running, supported by the Serverless Framework. I need one lambda (called lambdaOne) which will call a second lambda (called lambdaTwo) using AWS' javascript sdk. The issue is that I am getting an AccessDenied Exception when I attempt this:

UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): AccessDeniedException: User: arn:aws:sts::12345678909876:assumed-role/test-dev-us-west-2-lambdaRole/test-dev-lambdaOne is not authorized to perform: lambda:Invoke Function on resource: arn:aws:lambda:us-west-2:994979977450:function:test-dev-lambdaTwo

To my understanding, Serverless creates a default IAM role for all lambda functions. So, I should be able to just to add a new entry under iamRoleStatements.

My confusion arises from the fact that the resource I want to reference (lambdaTwo) is already defined as a function.

Is there a way to reference a function as a resource?

I have several AWS lambdas running, supported by the Serverless Framework. I need one lambda (called lambdaOne) which will call a second lambda (called lambdaTwo) using AWS' javascript sdk. The issue is that I am getting an AccessDenied Exception when I attempt this:

UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): AccessDeniedException: User: arn:aws:sts::12345678909876:assumed-role/test-dev-us-west-2-lambdaRole/test-dev-lambdaOne is not authorized to perform: lambda:Invoke Function on resource: arn:aws:lambda:us-west-2:994979977450:function:test-dev-lambdaTwo

To my understanding, Serverless creates a default IAM role for all lambda functions. So, I should be able to just to add a new entry under iamRoleStatements.

My confusion arises from the fact that the resource I want to reference (lambdaTwo) is already defined as a function.

Is there a way to reference a function as a resource?

Share Improve this question asked May 17, 2017 at 18:47 KJ PriceKJ Price 5,9843 gold badges23 silver badges36 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 3

Currently, there is no shortcut to declare permissions for a Lambda function. You need to give permissions based on its ARN.

Below follows a working example.

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.
              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);
};

You can also use serverless-iam-roles-per-function plugin which allow you to attach individual IAM role per lambda function and in bination with serverless-pseudo-parameters you can reference the other lambda.

发布评论

评论列表(0)

  1. 暂无评论