3

I have created a user in the AWS console with access only to the Lambda service.

My question is, using the serverless framework, in my serverless.yaml, is it possible to add S3 Full access to my user and possibly any other service? Thank you.

handler.js

 'use strict';
const aws = require('aws-sdk');
const s3 =  new aws.S3({ apiVersion: '2006-03-01' });

module.exports.helloWorld = (event, context, callback) => {

  const params = {};
  s3.listBuckets(params, function(err, data) {
    if (err) console.log(err, err.stack); 
    else     console.log(data);          
  });

  const response = {
    statusCode: 200,
    message: JSON.stringify({message: 'Success!'})
  };
  callback(null, response);
};

serverless.yaml

provider:
  name: aws
  runtime: nodejs8.10
  region: eu-blah-1
  iamRoleStatements:
    - Effect: "Allow"
      Action:
        - "s3:ListBucket"
        - "s3:PutObject"
        - "s3:GetObject"
      Resource: "arn:aws:s3:::examplebucket/*"


functions:
  helloWorld:
    handler: handler.helloWorld
    events:
      - http:
          path: hello-world
          method: get
          cors: true
squeekyDave
  • 918
  • 2
  • 16
  • 35
  • 2
    Who is the "user", is this an IAM User with API Credentials that you use to deploy the Serverless Service, or is this something to do with the permissions that you want the Lambda function deployed to have? – Matt D Sep 27 '18 at 16:17

1 Answers1

2

If you are referring to the permissions that you give to the Lambda Function to have at execution time, after it has been deployed by the Serverless Framework, then you add role permissions in the serverless.yaml file, within the provider section.

Here is an example of permissions for the Lambda to talk to S3, Execute other Lambdas, and Send Emails with SES:

iamRoleStatements:
  - Effect: "Allow"
    Action:
      - "s3:PutObject"
      - "s3:DeleteObject"
      - "s3:DeleteObjects"
    Resource: arn:aws:s3:::${self:custom.s3WwwBucket}/content/pages/*
  - Effect: Allow
    Action:
      - lambda:InvokeFunction
      - lambda:InvokeAsync
    Resource: arn:aws:lambda:${self:custom.region}:*:function:${self:service}-${opt:stage}-*
  - Effect: "Allow"
    Action:
      - "ses:SendEmail"
      - "ses:SendEmailRaw"
    Resource: "arn:aws:ses:eu-west-1:01234567891234:identity/noreply@example.com"
Matt D
  • 3,289
  • 1
  • 15
  • 29
  • Can you please explain how the Resource: arn:aws:s3:::${self:custom.s3WwwBucket}/content/pages/* line works please? Thanks! – squeekyDave Sep 28 '18 at 10:50
  • 1
    `${self:custom.s3WwwBucket}` is a reference to the custom values in the `serverless.yml`. `content/pages/*` is a sub key (like folders) of the allowed objects. You could add the bucketname explicitly with all objects within it, e.g. `arn:aws:s3:::example-bucket-name/*` – Matt D Sep 28 '18 at 11:51
  • 1
    Read more about AWS ARNs here: https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html – Matt D Sep 28 '18 at 11:53
  • thank you for the explanation, but I still get access denied. I will add the code from lambda and the code from serverless.yaml – squeekyDave Sep 28 '18 at 14:38
  • At what point do you get access denied? When deploying the serverless service, or when executing the Lambda Function? – Matt D Sep 28 '18 at 20:46
  • When I invoke it. I had a look at the role my lambda function gets and there is no policy in the role that specifies any S3 access even after I define them in the yaml file which confuses me. – squeekyDave Sep 28 '18 at 21:39
  • 1
    You are listing the buckets in your account `s3:ListBuckets` which is different to listing the contents off a bucket `s3:ListBucket`. You need to add `s3:ListBuckets` to do the action in your code. – Matt D Sep 29 '18 at 21:20