Configuring AWS Lambda to access S3 Bucket
Asked Answered
S

1

5

I just can't figure out what is wrong with my Bucket Policy in AWS. Trying to let a Lambda function to access and read an email from the S3 Bucket. But I keep getting "Access Denied"

Please note that I notice the email file is being created in the bucket. Here is my last version of the Bucket Policy:

{
    "Version": "2012-10-17",
    "Id": "Lambda access bucket policy",
    "Statement": [
        {
            "Sid": "All on objects in bucket lambda",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::[MY NUMBER]:root"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::[MY BUCKET NAME]/*"
        }
    ]
}

I have tried also with "Principal": {"Service": "ses.amazonaws.com"}, alas

I keep getting Access Denied:

2017-09-17T14:12:14.231Z 10664101-9bb2-11e7-ad43-539f3e1a8626
{
    "errorMessage": "Access Denied",
    "errorType": "AccessDenied",
    "stackTrace": [
        "Request.extractError (/var/runtime/node_modules/aws-sdk/lib/services/s3.js:577:35)",
        "Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:105:20)",
        "Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:77:10)",
        "Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:683:14)",
        "Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10)",
        "AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12)",
        "/var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10",
        "Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9)",
        "Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:685:12)",
        "Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:115:18)"
    ]
}

And here is my Lambda function:

var AWS = require('aws-sdk');
var s3 = new AWS.S3();

var bucketName = '[MY BUCKET NAME]';

exports.handler = function(event, context, callback) {
    console.log('Process email');

    var sesNotification = event.Records[0].ses;
    if(!sesNotification) {
        callback(null, null);
        return;
    }

    console.log("SES Notification:\n", JSON.stringify(sesNotification, null, 2));

    // Retrieve the email from your bucket
    s3.getObject({
            Bucket: bucketName,
            Key: sesNotification.mail.messageId
        }, function(err, data) {
            if (err) {
                console.log(err, err.stack);
                callback(err);
            } else {
                console.log("Raw email:\n" + data.Body);

                // Custom email processing goes here

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

After long time and many versions of the Bucket Policy I am thinking of trying another solution and drop AWS.

Any ideas ?

Satchel answered 17/9, 2017 at 14:24 Comment(0)
W
9

You need to create an IAM role and attach it to the Lambda function with S3FullAccess policy or with finegrained permission for the specific bucket and actions (Recommended).

Also make sure trust relationship configuration is added to the role.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "lambda.amazonaws.com"
        ]
      }
    }
  ]
}

Note: In your current setup, it seems like you have configured the bucket policy which grants read access to the root user.

Workable answered 17/9, 2017 at 14:32 Comment(7)
thanks for the answer. I have created an IAM user with fullS3Access. Yet I couldn't find where I attach it to the Lambda function nor where can I add it to the S3 Bucket ...Satchel
You need to create an IAM role instead of a user and also add the trust relationships for Lambda inside the role (Apart from the policy). Check the updated answerWorkable
Did both. Still get "Access Denied". What should be my Policy Bucket Principal ?Satchel
For testing purposes. First remove the bucket policy you added from S3. Create a iam role with s3 full access and with the mentioned trust relationship. Then attach the role to lambda and tryout?Workable
Thanks. Now I get "The specific key does not exist" which is another problem :-)Satchel
please update the answer regarding attaching the S3FullAccess to the Lambda Role and I will set is the chosen answer.Satchel
I have updated the answer. Also mote that for security it is recommended to whitelist the specific bucket resource and actions within the policy.Workable

© 2022 - 2024 — McMap. All rights reserved.