amazon web services - the - función aws lambda que obtiene acceso denegado cuando getObject desde s3
precios amazon lambda (7)
Curiosamente, AWS devuelve 403 (acceso denegado) cuando el archivo no existe. Asegúrate de que el archivo esté en el cubo
Estoy accediendo a un error denegado del servicio S3 aws en mi función lambda
este es el código
// dependencies
var async = require(''async'');
var AWS = require(''aws-sdk'');
var gm = require(''gm'').subClass({ imageMagick: true }); // Enable ImageMagick integration.
exports.handler = function(event, context) {
var srcBucket = event.Records[0].s3.bucket.name;
// Object key may have spaces or unicode non-ASCII characters.
var key = decodeURIComponent(event.Records[0].s3.object.key.replace(//+/g, " "));
/*
{
originalFilename: <string>,
versions: [
{
size: <number>,
crop: [x,y],
max: [x, y],
rotate: <number>
}
]
}*/
var fileInfo;
var dstBucket = "xmovo.transformedimages.develop";
try {
//TODO: Decompress and decode the returned value
fileInfo = JSON.parse(key);
//download s3File
// get reference to S3 client
var s3 = new AWS.S3();
// Download the image from S3 into a buffer.
s3.getObject({
Bucket: srcBucket,
Key: key
},
function (err, response) {
if (err) {
console.log("Error getting from s3: >>> " + err + "::: Bucket-Key >>>" + srcBucket + "-" + key + ":::Principal>>>" + event.Records[0].userIdentity.principalId, err.stack);
return;
}
// Infer the image type.
var img = gm(response.Body);
var imageType = null;
img.identify(function (err, data) {
if (err) {
console.log("Error image type: >>> " + err);
deleteFromS3(srcBucket, key);
return;
}
imageType = data.format;
//foreach of the versions requested
async.each(fileInfo.versions, function (currentVersion, callback) {
//apply transform
async.waterfall([async.apply(transform, response, currentVersion), uploadToS3, callback]);
}, function (err) {
if (err) console.log("Error on excecution of watefall: >>> " + err);
else {
//when all done then delete the original image from srcBucket
deleteFromS3(srcBucket, key);
}
});
});
});
}
catch (ex){
context.fail("exception through: " + ex);
deleteFromS3(srcBucket, key);
return;
}
function transform(response, version, callback){
var imageProcess = gm(response.Body);
if (version.rotate!=0) imageProcess = imageProcess.rotate("black",version.rotate);
if(version.size!=null) {
if (version.crop != null) {
//crop the image from the coordinates
imageProcess=imageProcess.crop(version.size[0], version.size[1], version.crop[0], version.crop[1]);
}
else {
//find the bigger and resize proportioned the other dimension
var widthIsMax = version.size[0]>version.size[1];
var maxValue = Math.max(version.size[0],version.size[1]);
imageProcess=(widthIsMax)?imageProcess.resize(maxValue):imageProcess.resize(null, maxValue);
}
}
//finally convert the image to jpg 90%
imageProcess.toBuffer("jpg",{quality:90}, function(err, buffer){
if (err) callback(err);
callback(null, version, "image/jpeg", buffer);
});
}
function deleteFromS3(bucket, filename){
s3.deleteObject({
Bucket: bucket,
Key: filename
});
}
function uploadToS3(version, contentType, data, callback) {
// Stream the transformed image to a different S3 bucket.
var dstKey = fileInfo.originalFilename + "_" + version.size + ".jpg";
s3.putObject({
Bucket: dstBucket,
Key: dstKey,
Body: data,
ContentType: contentType
}, callback);
}
};
Este es el error en cloudwatch
AccessDenied: Access Denied
Este es el error de la pila
at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/services/s3.js:329: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:596:14)
at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:21:10)
at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:37:9)
at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:598:12)
at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:115:18)
Sin ninguna otra descripción o información sobre los permisos de cubo s3, permite a todos colocar la lista y eliminar
¿Qué puedo hacer para acceder al cubo S3?
PD: en las propiedades del evento lambda, el principal es correcto y tiene privilegios administrativos
Esto tal vez sea útil para algunas personas.
Si aún recibe el error de Acceso denegado incluso después de configurar el rol de IAM correcto con las políticas de permiso s3, asegúrese de que su código sea correcto. Tenía un error en mi código y se mostraba en los registros como denegado.
Estuve luchando con este problema durante horas. Estaba usando AmazonS3EncryptionClient y nada de lo que hice ayudó. Luego noté que el cliente está en desuso, así que pensé en intentar cambiar al modelo de generador que tienen:
var builder = AmazonS3EncryptionClientBuilder.standard()
.withEncryptionMaterials(new StaticEncryptionMaterialsProvider(encryptionMaterials))
if (accessKey.nonEmpty && secretKey.nonEmpty) builder = builder.withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(accessKey.get, secretKey.get)))
builder.build()
Y ... eso lo resolvió. Parece que Lambda tiene problemas para inyectar las credenciales en el modelo anterior, pero funciona bien en el nuevo.
Me encontré con este problema y después de horas de locura política de IAM, la solución fue:
- Ir a la consola S3
- Haz clic en el cubo que te interesa.
- Haga clic en ''Propiedades''
- Desplegar ''Permisos''
- Haga clic en ''Agregar más permisos''
- Elija ''Cualquier usuario de AWS autenticado'' del menú desplegable. Seleccione ''Cargar / Eliminar'' y ''Lista'' (o lo que sea que necesite para su lambda).
- Clic en Guardar''
Hecho. Sus políticas de roles de IAM cuidadosamente escritas no importan, ni tampoco las políticas de cubos específicos (también las he escrito para que funcionen). O simplemente no funcionan en mi cuenta, quién sabe.
[EDITAR]
Después de muchos retoques, el enfoque anterior no es el mejor. Prueba esto:
- Mantenga su política de roles como en la publicación de helloV.
- Ve a S3. Seleccione su cubo Haga clic en Permisos. Haga clic en Política de cubos.
- Pruebe algo como esto:
{ "Version": "2012-10-17", "Id": "Lambda access bucket policy", "Statement": [ { "Sid": "All on objects in bucket lambda", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::AWSACCOUNTID:root" }, "Action": "s3:*", "Resource": "arn:aws:s3:::BUCKET-NAME/*" }, { "Sid": "All on bucket by lambda", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::AWSACCOUNTID:root" }, "Action": "s3:*", "Resource": "arn:aws:s3:::BUCKET-NAME" } ] }
Funcionó para mí y no requiere que lo compartas con todos los usuarios de AWS autenticados (lo que la mayoría de las veces no es ideal).
Si está especificando el Recurso , no olvide agregar la especificación de la subcarpeta también. Me gusta esto:
"Resource": [
"arn:aws:s3:::BUCKET-NAME",
"arn:aws:s3:::BUCKET-NAME/*"
]
Su Lambda no tiene privilegios (S3:GetObject)
.
Vaya al panel IAM, verifique el rol asociado con su ejecución de Lambda. Si usa el asistente de AWS, crea automáticamente una función llamada oneClick_lambda_s3_exec_role
. Haga clic en Show Policy
. Debería mostrar algo similar a la imagen adjunta. Asegúrese de que S3:GetObject
lista.
También me encontré con este problema, lo arreglé proporcionando s3:GetObject*
en la ACL, ya que está intentando obtener una versión de ese objeto.