![](/img/trans.png)
[英]Access denied on aws lambda function when getObject from S3 bucket
[英]Not getting results when attempting to read the content of an S3 bucket from AWS Lambda function in Nodejs
在將 dynamodb 表從不同賬戶跨賬戶遷移到我們自己的 AWS 賬戶后,我需要使用 nodejs lambda 來讀取和處理包含 json 的文本文件。 通過創建 EMR 集群運行導入作業的源 AWS Datapipeline 在源賬戶(不是我們的賬戶)的 S3 存儲桶中刪除了 5 MB 文件,對象鍵的格式為dynamodbtablename/manifest
和dynamodbtablename/2c561e6c-62ba-4eab-bf21-7f685c7c3129
。 清單文件包含以下示例數據:
{"name":"DynamoDB-export","version":3,
"entries": [
{"url":"s3://bucket/dynamodbtablename/2c561e6c-62ba-4eab-bf21-7f685c7c3129","mandatory":true}
]}
我今天大部分時間都在努力閱讀清單文件。 雖然在 lambda 中沒有遇到訪問問題,但我最初必須處理在 terraform 中設置資源的跨賬戶策略和權限。 我現在的問題是調用s3.getObject
的代碼似乎沒有被命中。
/* eslint-disable no-console, no-param-reassign */
const AWS = require('aws-sdk');
const massiveTables = [
'dynamodbtablename'
];
function getS3Objects(params) {
let s3 = new AWS.S3({
apiVersion: '2012-10-29'
});
return new Promise((resolve, reject) => {
s3.getObject(params, (err, data) => {
if (err) {
reject(err);
} else {
resolve(data);
}
});
});
}
const handler = async ({ Records }) => {
const completelyProcessedSNSPromises = Records.map(async ({ Sns: { Message: tableName } }) => {
console.log(`tableName: ${tableName}`);
let massiveTableItem = tableName.trim();
console.log(`massiveTableItem: ${massiveTableItem}`);
//#1: Validate the the right table names are coming through
if (massiveTables.includes(massiveTableItem)) {
//#2: Use the table name to fetch the right keys from the S3 bucket
let params = {
Bucket: process.env.DATA_BUCKET,
Key: `${massiveTableItem}/manifest`,
ResponseContentType: 'application/json'
};
getS3Objects(params)
.then(result => {
console.log(`result: ${result}`);
})
.catch(error => {
console.log(`error: ${error}`);
});
}
});
await Promise.all(completelyProcessedSNSPromises)
.then(console.log)
.catch(console.error);
};
module.exports.handler = handler;
這就是我在 Cloudwatch 日志中得到的信息
16:13:25
2020-03-11T16:13:25.271Z 8bd74c44-c9b1-4cd9-a360-251ad4253eae INFO tableName: dynamodbtablename
2020-03-11T16:13:25.271Z 8bd74c44-c9b1-4cd9-a360-251ad4253eae INFO tableName: dynamodbtablename
16:13:25
2020-03-11T16:13:25.271Z 8bd74c44-c9b1-4cd9-a360-251ad4253eae INFO massiveTableItem: dynamodbtablename
2020-03-11T16:13:25.271Z 8bd74c44-c9b1-4cd9-a360-251ad4253eae INFO massiveTableItem: dynamodbtablename
16:13:25
2020-03-11T16:13:25.338Z 8bd74c44-c9b1-4cd9-a360-251ad4253eae INFO [ undefined ]
2020-03-11T16:13:25.338Z 8bd74c44-c9b1-4cd9-a360-251ad4253eae INFO [ undefined ]
請幫助我知道我做錯了什么。
非常感謝您提前。 PS:我是 Nodejs/Javascript 的新手
您需要在處理程序函數中返回getS3Objects
調用。 您沒有返回,因此 map 不會返回 promise,因此不會調用它。
此外,aws-sdk 支持承諾,因此您無需將它們包裝在承諾中。 像這樣的東西
/* eslint-disable no-console, no-param-reassign */
const AWS = require("aws-sdk");
const massiveTables = [
"dynamodbtablename"
];
function getS3Objects(params) {
const s3 = new AWS.S3({
"apiVersion": "2012-10-29"
});
return s3.getObject(params).promise();
}
// eslint-disable-next-line func-style
const handler = async ({Records}) => {
const completelyProcessedSNSPromises = Records.map(async ({"Sns": {"Message": tableName}}) => {
console.log(`tableName: ${tableName}`);
const massiveTableItem = tableName.trim();
console.log(`massiveTableItem: ${massiveTableItem}`);
// #1: Validate the the right table names are coming through
if (massiveTables.includes(massiveTableItem)) {
// #2: Use the table name to fetch the right keys from the S3 bucket
const params = {
"Bucket": process.env.DATA_BUCKET,
"Key": `${massiveTableItem}/manifest`,
"ResponseContentType": "application/json"
};
return getS3Objects(params);
}
});
await Promise.all(completelyProcessedSNSPromises)
.then(console.log)
.catch(console.error);
};
module.exports.handler = handler;
謝謝大家的幫助。
我發現問題是我在異步 lambda 處理程序中調用的異步函數由於無法訪問封閉的異步 lambda 處理程序范圍的范圍問題而無法執行。 這發生在使用數組映射和 forEach 函數時。
我求助於使用傳統的 for 循環。
for (let i = 0; i < Records.length; i++) {
const tableName = Records[i].Sns.Message;
console.log(`DAZN tableName: ${tableName}`);
const tableIndex = daznTables.findIndex(t => tableName.includes(t));
const massiveTableItem = massiveTables[tableIndex];
console.log(`massiveTableItem: ${massiveTableItem}`);
const dataBucket = process.env.DATA_BUCKET;
}
由於實際上並不需要從 .map 函數返回任何內容,因此我擺脫了
await Promise.all(completelyProcessedSNSPromises)
.then(console.log)
.catch(console.error);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.