【问题标题】:AWS: Uploading Files via Lambda to S3 Bucket not working ( Reading is )AWS:通过 Lambda 将文件上传到 S3 存储桶不起作用(正在阅读)
【发布时间】:2020-03-30 14:06:47
【问题描述】:

我正在使用 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);

据我了解,现在两个 lambda 函数( 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 });

【问题讨论】:

  • 代码看起来很合理。您能否包含调用的整个 CloudWatch 日志(混淆任何敏感部分)?从 START 日志到 END 和最终报告。
  • 如果此函数已成功部署为 lambda,它应该已生成日志。
  • 还要检查您的 Lambda 分配的 IAM 角色是否有权将日志写入 Cloudwatch
  • 我添加了完整的日志,虽然很小,但正如我们所见,包含了 lambda 函数的“console.log”输出。好像动作 s3.upload(...) 没有执行?
  • 您是否配置了超时。看起来 lambda 没有完成执行

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


【解决方案1】:

【讨论】:

  • 谢谢,但 cloudwatch 是我开发的核心工具之一。我只是想知道为什么我在 cloudwatch 中看不到(错误)行为 :)
  • 你是如何创建 lambda 的,你使用的是无服务器框架
  • 我正在使用 cdk 来部署 lambda。所以我们在这里是无服务器和无状态的。
【解决方案2】:

好的,谢谢大家,我找到了一个可行的解决方案。基本上我们可以等待 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);
};

【讨论】:

    猜你喜欢
    • 2018-04-25
    • 1970-01-01
    • 2019-07-09
    • 1970-01-01
    • 2021-02-07
    • 1970-01-01
    • 1970-01-01
    • 2019-07-19
    • 2018-09-29
    相关资源
    最近更新 更多