AWS:无法通过Lambda将文件上传到S3存储桶(正在读取)

时间:2019-12-05 15:40:20

标签: amazon-web-services amazon-s3 aws-lambda

我正在使用aws cdk创建必要的资源,因此为此我创建了

  • 一个用于保存文件的s3容器
  • 一个lambda可以将文件发布到s3存储桶
  • 一个lambda从s3存储桶中获取文件

使用以下设置创建S3容器:

 const imageBucketProps: BucketProps = {
     bucketName: awsReferences.S3_SCREENSHOT_CONTAINER_BUCKET_NAME,
     publicReadAccess: true,
  };
 const imageBucket = new Bucket(this, id, imageBucketProps);

 imageBucket.grantReadWrite(getImageFunction);
 imageBucket.grantReadWrite(postImageFunction);

据我所知,现在两个lambdafunctions(getImageFunction和postImageFunction)都被授予以完全权限访问此存储桶(我正在按预期的方式更改为正确的权限)

我手动将文件上传到名为mr_base.jpg的存储桶中,并且可以使用以下getImageFunction从存储桶中获取FileBuffer:

const AWS = require('aws-sdk');
const s3 = new AWS.S3();
const awsReferences = require('./lib/config/aws_references.json');

exports.handler = (event, context, callback) => {
   let imageKey = 'mr_base.jpg';

   // prepare parameters for Bucket Get Request
   const params = {
      Bucket: awsReferences.S3_SCREENSHOT_CONTAINER_BUCKET_NAME,
      Key: imageKey,
   };

   s3.getObject(params, function(err, data) {
      if (err) {
         callback(err, null);
      } else {
         let response = {
            statusCode: 200,
            headers: {},
            body: JSON.stringify(data),
            isBase64Encoded: false,
         };
         callback(null, response);
      }
   });
};

所以我验证了:

  • Lambda执行成功,没有错误
  • S3容器已存在
  • 授予lambda函数对S3容器的读取访问权限

现在,我想将文件(图像)上传到该文件夹​​,并且我在此处使用文本文件来简化此操作,以免在其中复制粘贴缓冲区。

postImageFunction也非常简单:

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

const awsReferences = require('./lib/config/aws_references.json');

exports.handler = async (event, context, callback) => {
   console.log('S3 Get Function has been called');

   let filename = 'file_' + Date.now() + '_' + 'user_id' + '.txt';
   let content = 'hi i am your content';

   var filePath = filename;

   const params = {
      Body: content,
      Bucket: awsReferences.S3_SCREENSHOT_CONTAINER_BUCKET_NAME,
      Key: filePath,
   };

   console.log('s3 Upload s3 params', params);

   s3.upload(params, function(err, data) {
      console.log('s3 upload function called at', Date.now());
      if (err) {
         console.log('error', err);
         callback(err, null);
      } else {
         console.log('data', data);

         let response = {
            statusCode: 200,
            headers: {
               my_header: 'my_value',
            },
            body: JSON.stringify(data),
            isBase64Encoded: false,
         };
         callback(null, response);
      }
   });
};

不幸的是,我在Cloudwatch中看不到任何错误,也无法获取其中的任何日志

s3.upload(params, function(err, data) { … }

我在这里验证的内容:

  • s3是一个对象,其中包含与AWS相关的信息
  • params也是具有预期键和值的对象

我经历了很多次访问权限可能是一个问题,但是Cloudwatch一直在这里提供有关任何问题的日志。不幸的是,我不知道这里发生了什么。

我错过了什么吗?这看起来很简单,而且教程也很像

https://medium.com/think-serverless/image-upload-and-retrieval-from-s3-using-aws-api-gateway-and-lambda-b4c2961e8d1

似乎是指相同的代码。

我很感谢任何提示,即使起初是手动设置,我也想出了如何在cdk中实现等效功能。 :)

一次调用的Cloudwatch日志:

START RequestId: dcf92d06-0f27-4495-a1e3-87419fc43a70 Version: $LATEST
2019-12-06T09:23:29.896Z	dcf92d06-0f27-4495-a1e3-87419fc43a70	INFO	S3 Get Function has been called
2019-12-06T09:23:29.899Z	dcf92d06-0f27-4495-a1e3-87419fc43a70	INFO	s3 Upload s3 params { Body: 'hi i am your content',
  Bucket: 'screen-shot-container-bucket',
  Key: 'file_1575624209897_user_id.txt' }
END RequestId: dcf92d06-0f27-4495-a1e3-87419fc43a70
REPORT RequestId: dcf92d06-0f27-4495-a1e3-87419fc43a70	Duration: 59.62 ms	Billed Duration: 100 ms	Memory Size: 1024 MB	Max Memory Used: 95 MB	Init Duration: 379.97 ms

更新:

我创建了一个IAM用户(AmazonS3FullAccess),并使用该用户的凭证更新了配置。但结果相同。

const { ACCESS_KEY_ID, SECRET_ACCESS_KEY, AWS_REGION } = process.env;
AWS.config.update({ accessKeyId: ACCESS_KEY_ID, secretAccessKey: SECRET_ACCESS_KEY, region: AWS_REGION });

2 个答案:

答案 0 :(得分:0)

答案 1 :(得分:0)

好的,谢谢大家,我找到了一个可行的解决方案。基本上,我们可以等待s3.upload方法,然后将其简化为以下代码。 (由于授予了权限,因此不需要额外的IAM用户)

这对我来说很有意义,因为上传需要一些时间

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

const awsReferences = require('./lib/config/aws_references.json');

exports.handler = async (event, context) => {
   console.log('S3 Get Function has been called');

   let filename = 'file_' + Date.now() + '_' + 'user_id' + '.txt';
   let content = 'hi i am your content';

   var filePath = filename;

   const params = {
      Body: content,
      Bucket: awsReferences.S3_SCREENSHOT_CONTAINER_BUCKET_NAME,
      Key: filePath,
   };

   try {
      const { Location, Key } = await s3.upload(params).promise();
      location = Location;
      key = Key;
   } catch (error) {}

   console.log(location, key);
};