Я создал лямбда-функцию и роль в соответствии с примером для создания миниатюр (https://docs.aws.amazon.com/lambda/latest/dg/with-s3-example.html)) и получил его на работу. Я пытаюсь настроить его в соответствии с нашими конкретными потребностями, и вдруг ошибка «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
Политика была настроена в соответствии с примером. Я даже пытался установить определенную настраиваемую политику для лямбда-роли с более конкретными разрешениями для создания объектов в этом сегменте.
Пример политики:
{
"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": "*"
}
]
}
Лямбда-код:
// 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");
}
);
};
Одна из вещей, которые я пытаюсь сделать при создании новых файлов, - поместить их в отдельные «подпапки» с помощью ключевого префикса на основе числового идентификатора. Так, например, будет загружено новое изображение (с помощью dropzone.js) в виде «12345 / image.jpg». У меня уже есть файлы и миниатюры, чтобы работать с такой простой строкой, как 'john'. Я подумал, что, может быть, номер напортачил, поэтому я попробовал 'user12345 / image.jpg'
Изображение загружается в первый контейнер, но лямбда-функция завершается ошибкой с сообщением ACCESS_DENIED, упомянутым выше.
Любая помощь приветствуется