access denied in lambda when trying to access file

2019-08-26 18:13发布

问题:

Following on from the great help I received on my original post

Uploading a file to an s3 bucket, triggering a lambda, which sends an email containing info on the file uploaded to s3 buket

I have tested previously sending the email so I know that works but when I try to include the data of the upload it fires error

Could not fetch object data:  { AccessDenied: Access Denied
at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/services/s3.js:577:35)
at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:683:14)

I have found many q's related to this online regarding policies around roles etc..So I have added lambda to the s3 event, and added s3 permission to the role eg.

https://stackoverflow.com/questions/35589641/aws-lambda-function-getting-access-denied-when-getobject-from-s3

Unfortunately none of these have helped. I noticed a comment however

Then the best solution is to allow S3FullAccess, see if it works. If it does, then remove one set of access at a time from the policy and find the least privileges required for your Lambda to work. If it does not work even after giving S3FullAccess, then the problem is elsewhere

So how would I go about finding where the problem is?

Thank Y

   'use strict';

console.log('Loading function');

var aws = require('aws-sdk');
var ses = new aws.SES({
   region: 'us-west-2'
});
//var fileType = require('file-type');

console.log('Loading function2');

var s3 = new aws.S3({ apiVersion: '2006-03-01', accessKeyId: process.env.ACCESS_KEY, secretAccessKey: process.env.SECRET_KEY, region: process.env.LAMBDA_REGION });

console.log('Loading function3');
//var textt = "";

exports.handler = function(event, context) {
    console.log("Incoming: ", event);

  //  textt = event.Records[0].s3.object.key;
   // var output = querystring.parse(event);

   //var testData = null;

   // Get the object from the event and show its content type
   // const bucket = event.Records[0].s3.bucket.name;
   // const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
    const params = {
       Bucket: 'bucket',
       Key: 'key',
    };

    s3.getObject(params, function(err, objectData) {
    if (err) {
        console.log('Could not fetch object data: ', err);
    } else {
        console.log('Data was successfully fetched from object');
        var eParams = {
            Destination: {
                ToAddresses: ["fake@fake.com"]
            },
            Message: {
                Body: {
                    Text: {
                        Data: objectData
                       // Data: textt
                    }
                },
                Subject: {
                    Data: "Email Subject!!!"
                }
            },
            Source: "fake@fake.com"
        };

        console.log('===SENDING EMAIL===');

        var email = ses.sendEmail(eParams, function(err, emailResult) {
            if (err) console.log('Error while sending email', err);
            else {
                console.log("===EMAIL SENT===");
                //console.log(objectData);
                console.log("EMAIL CODE END");
                console.log('EMAIL: ', emailResult);
                context.succeed(event);
            }
        });
    }
});

};

UPDATE I have added comments to the code and checked the logs...it doesnt go past this line

var s3 = new aws.S3({ apiVersion: '2006-03-01', accessKeyId: process.env.ACCESS_KEY, secretAccessKey: process.env.SECRET_KEY, region: process.env.LAMBDA_REGION });

Is this anyway related to access denied?

NOTE: ALL I WANT IN THE FILENAME OF THE UPLOADED FILE

UPDATE 2

iv replaced the line causing issue with var s3 = new aws.S3().getObject({ Bucket: this.awsBucketName, Key: 'keyName' }, function(err, data) { if (!err) console.log(data.Body.toString()); });

but this is firing as TypeError: s3.getObject is not a function

Also tried...var s3 = new aws.S3();

this is back to the original error of Could not fetch object data: { AccessDenied: Access Denied

回答1:

First of all region should be S3 bucket region and not lambda region. Next you need to verify your credentials and if they have access to S3 bucket you have defined. As you stated in one of the comment try attaching S3 full access Amazon managed policy to your IAM user which is associated with credentials you are using in Lambda. Next step would be use aws cli to see if you can access this bucket. Maybe something like -

aws s3 ls

Having said above you should not use credentials at all. Since Lambda and S3 are amazon services you should use roles. Just give Lambda a role that gives it full access to S3 and do not use aws IAM credentials for this. And

var s3 = new AWS.S3();

is sufficient.