[英]I can't access my node.js server on my AWS EC2 isntance from the outside
[英]How can I list all my Amazon EC2 instances using Node.js in AWS Lambda?
我在 AWS 上並在 Node.js 中使用 AWS SDK for JavaScript 。 我正在嘗試構建一個 AWS Lambda 函數,在里面我想獲取我所有的 Amazon EC2 實例的列表,但我似乎無法讓它工作。 誰能發現我做錯了什么?
這是我的 Lambda 函數代碼:
var AWS = require('aws-sdk');
AWS.config.region = 'us-west-1';
exports.handler = function(event, context) {
console.log("\n\nLoading handler\n\n");
var ec2 = new AWS.EC2();
ec2.describeInstances( function(err, data) {
console.log("\nIn describe instances:\n");
if (err) console.log(err, err.stack); // an error occurred
else console.log("\n\n" + data + "\n\n"); // successful response
});
context.done(null, 'Function Finished!');
};
這是我的政策(我認為這是正確的?)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:*"
],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"ec2:*"
],
"Resource": "arn:aws:ec2:*"
},
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::*"
]
}
]
}
如果我在'ec2'上執行console.log,我會得到:
{ config:
{ credentials:
{ expired: false,
expireTime: null,
accessKeyId: 'XXXXXXXXXXXXXXXXXX',
sessionToken: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
envPrefix: 'AWS' },
credentialProvider: { providers: [Object] },
region: 'us-west-1',
logger: null,
apiVersions: {},
apiVersion: null,
endpoint: 'ec2.us-west-1.amazonaws.com',
httpOptions: { timeout: 120000 },
maxRetries: undefined,
maxRedirects: 10,
paramValidation: true,
sslEnabled: true,
s3ForcePathStyle: false,
s3BucketEndpoint: false,
computeChecksums: true,
convertResponseTypes: true,
dynamoDbCrc32: true,
systemClockOffset: 0,
signatureVersion: 'v4' },
isGlobalEndpoint: false,
endpoint:
{ protocol: 'https:',
host: 'ec2.us-west-1.amazonaws.com',
port: 443,
hostname: 'ec2.us-west-1.amazonaws.com',
pathname: '/',
path: '/',
href: 'https://ec2.us-west-1.amazonaws.com/' } }
最可能的原因是您在 Lambda 函數完成對 EC2 DescribeInstances API 的調用之前明確終止了它。
原因是 Lambda 假定您的代碼在您調用context.done(...)
后立即執行完畢。 這發生在console.log(... data ...)
調用之前。
之所以會出現這種奇怪的排序,是因為 NodeJS 的工作方式以及 AWS SDK for JavaScript 的工作方式。 在 NodeJS 中,你永遠不應該阻止執行。 對 Web 服務(例如 EC2)的調用會阻止執行。 因此,適用於 JavaScript 的 AWS 開發工具包(以及大多數 NodeJS 庫)通過異步調用來工作。
大多數情況下,當您進行異步調用時,您會將回調函數傳遞給該調用。 當結果准備好后,NodeJS 會執行回調函數。
在您的代碼中,該function(err, data) {...}
是回調函數。 這不會立即執行,而是會在 NodeJS 看到ec2.describeInstances
調用已收到其結果時安排執行。
一旦你安排了回調的執行,你就會調用context.done(...)
,它告訴 Lambda:我完成了,你可以殺了我。 在 EC2 DescribeInstances 調用接收其數據並將其傳遞給您的回調函數之前,它很樂意服從並中斷您的函數。
如何解決問題?
答案現在應該很清楚了:只需將context.done(...)
調用移到回調函數內部,就在包含console.log(...data...)
調用的 if/else 塊之后:
ec2.describeInstances( function(err, data) {
console.log("\nIn describe instances:\n");
if (err) console.log(err, err.stack); // an error occurred
else console.log("\n\n" + data + "\n\n"); // successful response
context.done(null, 'Function Finished!');
});
截至 2019 年(10 月),給定的答案沒有幫助,挖掘后我發現現在它是基於承諾的
exports.handler = async function(event) {
const promise = new Promise(function(resolve, reject) {
//your logic, goes here at the end just call resolve
resolve("data you want to return"); // here lamda exits
})
return promise;// lamda does not exits here, it waits for to resolve
}
let data = await ec2.describeInstances();
return data;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.