Jor*_*die 13 amazon-ec2 amazon-web-services node.js 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!');
};
Run Code Online (Sandbox Code Playgroud)
这是我的政策(我认为这是正确的吗?)
{
"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:::*"
]
}
]
}
Run Code Online (Sandbox Code Playgroud)
如果我在'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/' } }
Run Code Online (Sandbox Code Playgroud)
Bru*_*eis 13
最可能的原因是您在完成对EC2 DescribeInstances API的调用之前显式终止了Lambda函数.
原因是Lambda假设您的代码在您调用后立即执行完毕context.done(...).这是在console.log(... data ...)电话会议之前发生的.
这种奇怪的排序是因为NodeJS的工作原理以及AWS SDK for JavaScript的工作原理.在NodeJS中,您永远不应该阻止执行.对Web服务(例如EC2)的调用将阻止执行.因此,AWS SDK for JavaScript(以及大多数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!');
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9948 次 |
| 最近记录: |