0

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

John
  • 3,965
  • 21
  • 77
  • 163

1 Answers1

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.

Aniket Thakur
  • 66,731
  • 38
  • 279
  • 289
  • Hey Aniket. thank you for replying....so....all s3 buckets are 'Global' region so I should change to that var ses = new aws.SES({ region: 'global' });.............Next off I didnt realise I had to add the permissions to the user...I only added them to the role that was used when creating the bucket....so to the user I have also added 'awsLambdaFullAccess, AmazonS3 Full access, administrator Access & Amazon SES full access'....I have tried all these and again thank you but I am still getting access denied – John Dec 07 '17 at 06:19
  • I think accessing the bucket is working, because if I room the code that captures the details of the file and I upload a picture to the s3 bucket, it triggers the lambda and sends an email...so this is all working. its just when I try to get the filename of the upload I get hit with accessDenied – John Dec 07 '17 at 06:22
  • How do you say access to bucket is working when it is actually failing? When you get upload something to S3 you get lambda triggered by event and you send mail. There is no s3 interaction from lambda that has worked for you. As I said before use roles and avoid credentials altogether. – Aniket Thakur Dec 07 '17 at 07:37
  • If I leave the lambda as it was before which just sends an email. This lamdba is connected to a trigger to the S3 bucket....When I upload an image into the bucket, it triggers the lambda and sends an email....this is working...so does this not mean access to the bucket is working? its only when I try to add in the code to get the content that was uploaded to the bucket that it fails. Im sorry but what do you mean by credentials as far as I know im not using credentials im using roles...In the s3 bucket I have added 'public access' in access control list – John Dec 07 '17 at 22:29
  • and in the lambda I have added the iam exection role which has access to awsLambdaFullAccess, Amazons3Fullaccess, administratorAccess, AmazonSesFUllAccess.....again thanks for helping but have you any idea what im doing wrong – John Dec 07 '17 at 22:29
  • Instead of `var s3 = new aws.S3({ apiVersion: '2006-03-01', accessKeyId: process.env.ACCESS_KEY, secretAccessKey: process.env.SECRET_KEY, region: process.env.LAMBDA_REGION });` use `var s3 = new aws.S3();` – Aniket Thakur Dec 08 '17 at 04:12
  • Thank you for the reply Aniket but I am still getting 'Could not fetch object data: { AccessDenied: Access Denied' – John Dec 11 '17 at 00:13
  • Do you have any bucket policy that is denying access to resources in bucket? – Aniket Thakur Dec 11 '17 at 03:33