Kappacake
Kappacake

Reputation: 1937

AWS Lambda Node.js - get output from async call (ec2.describeImages)

I am unable to get data from ec2.describeImages.

I have a function that wraps the call to ec2.describeImages:

async function GetLatestAMI (event, context, latestAMI) {
console.log("REQUEST RECEIVED:\n" + JSON.stringify(event));

var responseStatus = "FAILED";
var responseData = {};
var osBaseName = osNameToPattern[event.ResourceProperties.OSName];

console.log("OS: " + event.ResourceProperties.OSName + " -> " + osBaseName);

//var ec2 = new aws.EC2({region: event.ResourceProperties.Region});
var describeImagesParams = {
    Filters: [{ Name: "name", Values: [osBaseName]}],
    Owners: ["amazon"]
};

console.log( "Calling describeImages...");

// Get the available AMIs for the specified Windows version.
await ec2.describeImages(describeImagesParams, function(err, describeImagesResult) {
    if (err) {
        responseData = {Error: "DescribeImages call failed"};
        console.log(responseData.Error + ":\n", err);
    }
    else {
        console.log( "Got a response back from the server");

        var images = describeImagesResult.Images;

        console.log( "Got " + images.length + " images back" );

        // Sort the images by descending creation date order so the
        // most recent image is first in the array.
        images.sort(function(x,y){
            return x.CreationDate < y.CreationDate;
        });

        for (var imageIndex = 0; imageIndex < images.length; imageIndex++) {
            responseStatus = "SUCCESS";
            responseData["Id"] = images[imageIndex].ImageId;
            latestAMI = responseData["Id"];
            responseData["Name"] = images[imageIndex].Name;
            console.log( "Found: " + images[imageIndex].Name + ", " + images[imageIndex].ImageId);
            context.done(null, "success");
            //break;
            return latestAMI;
        }
    }
}).promise();}

I call this function on the Lambda handler:

exports.handler = async function(event, context, callback) { 

console.log("Hello!")

var latestAMI = "";
var testResult = await GetLatestAMI(event, context, latestAMI);
console.log("Test result: " +  latestAMI);
console.log("Test result: " +  testResult);
}

I cannot get any output from GetLatestAMI(). I have tried using a return clause inside the function as you can see and even passing a variable as an argument and edit the value of that value inside the function with no luck.

Here is the output from the console:

Response:
"success"

Request ID:
"8f2dbba4-02d1-11e9-a504-83ed96cb467a"

Function Logs:
START RequestId: 8f2dbba4-02d1-11e9-a504-83ed96cb467a Version: $LATEST
2018-12-18T14:31:08.858Z    8f2dbba4-02d1-11e9-a504-83ed96cb467a    Hello!
2018-12-18T14:31:08.873Z    8f2dbba4-02d1-11e9-a504-83ed96cb467a    REQUEST RECEIVED:
{"ResourceProperties":{"OSName":"Windows Server 2016 (64-bit)"}}
2018-12-18T14:31:08.873Z    8f2dbba4-02d1-11e9-a504-83ed96cb467a    OS: Windows Server 2016 (64-bit) -> Windows_Server-2016-English-Full-Base-*
2018-12-18T14:31:08.873Z    8f2dbba4-02d1-11e9-a504-83ed96cb467a    Calling describeImages...
2018-12-18T14:31:10.556Z    8f2dbba4-02d1-11e9-a504-83ed96cb467a    Got a response back from the server
2018-12-18T14:31:10.573Z    8f2dbba4-02d1-11e9-a504-83ed96cb467a    Got 7 images back
2018-12-18T14:31:10.593Z    8f2dbba4-02d1-11e9-a504-83ed96cb467a    Found: Windows_Server-2016-English-Full-Base-2018.12.12, ami-06a27ce600d784c71
END RequestId: 8f2dbba4-02d1-11e9-a504-83ed96cb467a
REPORT RequestId: 8f2dbba4-02d1-11e9-a504-83ed96cb467a  Duration: 1776.51 ms    Billed Duration: 1800 ms    Memory Size: 128 MB Max Memory Used: 39 MB  

I'm probably misunderstanding or missing something. Hopefully it would be obvious to someone with experience on AWS Lambda and Node.js!

Upvotes: 0

Views: 529

Answers (1)

Baldeep Singh Kwatra
Baldeep Singh Kwatra

Reputation: 1174

I have written the below lambda for you to list down the ec2 instances. And have checked in nodejs8.10. It is working as expected. Some of the issues your code has.

a) return statement inside loop.
b) context.done(null, "success"); done at wrong place that to inside loop
c) You are not resolving your promises anywhere.

Hope the Below code will give you an idea.

const AWS = require('aws-sdk');
module.exports.api = async (event, context, callback) => {
	var response = await getInstances();
	return {
		statusCode: '200',
		body: JSON.stringify({response}),
		headers: {'Content-Type': 'application/json'}
	}
}

async function getInstances() {
	var ec2 = new AWS.EC2();
	return new Promise(function (resolve, reject) {
		ec2.describeInstances(function (err, data) {
			if (err) reject(err);
			else resolve(data);
		});
	});
}

Upvotes: 2

Related Questions