我按照创建缩略图(https://docs.aws.amazon.com/lambda/latest/dg/with-s3-example.html)的示例创建了lambda函数和角色,并使其正常工作。我正在尝试根据自己的特定需求对其进行自定义,但是突然出现错误“ ACCESS_DENIED”,我不确定自己做了什么。
17:10:02
2019-07-11T17:10:02.007Z 301100e3-87c6-4c5e-b944-50c32cfd53aa Unable to resize my-bucket-test/user40226/7seg1_WEB.jpg and upload to my-thumbnails/user40226/7seg1_WEB.jpg due to an error: AccessDenied: Access Denied
2019-07-11T17:10:02.007Z 301100e3-87c6-4c5e-b944-50c32cfd53aa Unable to resize my-bucket-test/user40226/7seg1_WEB.jpg and upload to my-thumbnails/user40226/7seg1_WEB.jpg due to an error: AccessDenied: Access Denied
根据示例设置了策略。我什至尝试为lambda角色设置特定的自定义策略,并具有在该存储桶中创建对象的特定权限。
政策示例:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:*"
],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::*"
}
]
}
添加了自定义政策:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:ReplicateObject",
"s3:PutObject",
"s3:PutObjectRetention",
"s3:DeleteObjectVersion",
"s3:PutReplicationConfiguration",
"s3:RestoreObject",
"s3:UpdateJobPriority",
"s3:UpdateJobStatus",
"s3:DeleteObject",
"s3:PutBucketCORS",
"s3:PutBucketVersioning",
"s3:ReplicateDelete"
],
"Resource": "arn:aws:s3:::my-thumbnails"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "s3:CreateJob",
"Resource": "*"
}
]
}
lambda代码:
// dependencies
var async = require('async');
var AWS = require('aws-sdk');
var gm = require('gm')
.subClass({ imageMagick: true }); // Enable ImageMagick integration.
var util = require('util');
// constants
var MAX_WIDTH = 100;
var MAX_HEIGHT = 100;
// get reference to S3 client
var s3 = new AWS.S3();
exports.handler = function(event, context, callback) {
// Read options from the event.
console.log("Reading options from event:\n", util.inspect(event, {depth: 5}));
var srcBucket = event.Records[0].s3.bucket.name;
// Object key may have spaces or unicode non-ASCII characters.
var srcKey = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, " "));
var dstBucket = "my-thumbnails";
var dstKey = srcKey;
// Sanity check: validate that source and destination are different buckets.
//if (srcBucket == dstBucket) {
// callback("Source and destination buckets are the same.");
// return;
//}
// Infer the image type.
var typeMatch = srcKey.match(/\.([^.]*)$/);
if (!typeMatch) {
callback("Could not determine the image type.");
return;
}
var imageType = typeMatch[1].toLowerCase();
if (imageType != "jpg" && imageType != "png") {
callback(`Unsupported image type: ${imageType}`);
return;
}
// Download the image from S3, transform, and upload to a different S3 bucket.
async.waterfall([
function download(next) {
// Download the image from S3 into a buffer.
s3.getObject({
Bucket: srcBucket,
Key: srcKey
},
next);
},
function transform(response, next) {
gm(response.Body).size(function(err, size) {
// Infer the scaling factor to avoid stretching the image unnaturally.
var scalingFactor = Math.min(
MAX_WIDTH / size.width,
MAX_HEIGHT / size.height
);
var width = scalingFactor * size.width;
var height = scalingFactor * size.height;
// Transform the image buffer in memory.
this.resize(width, height)
.toBuffer(imageType, function(err, buffer) {
if (err) {
next(err);
} else {
next(null, response.ContentType, buffer);
}
});
});
},
function upload(contentType, data, next) {
// Stream the transformed image to a destination S3 bucket.
s3.putObject({
Bucket: dstBucket,
Key: dstKey,
Body: data,
ContentType: contentType,
ACL: 'public-read'
},
next);
}
], function (err) {
if (err) {
console.error(
'Unable to resize ' + srcBucket + '/' + srcKey +
' and upload to ' + dstBucket + '/' + dstKey +
' due to an error: ' + err
);
} else {
console.log(
'Successfully resized ' + srcBucket + '/' + srcKey +
' and uploaded to ' + dstBucket + '/' + dstKey
);
}
callback(null, "message");
}
);
};
在创建新文件时,我要尝试做的一件事情是通过基于数字ID的键前缀将它们放在单独的“子文件夹”中。因此,例如,将使用“ 12345 / image.jpg”之类的图片(使用dropzone.js)上传新图片。我已经有了像“ john”这样的测试字符串才能以这种方式工作的文件和缩略图。我以为可能是数字搞砸了,所以我尝试了'user12345 / image.jpg'
图像上传到第一个存储分区,但是lambda函数失败,并显示上述ACCESS_DENIED消息。
感谢您的帮助