0
votes

at present I am doing a lambda function in node.js to get information of my AWS account. I have an issue when I want to retrieve the information required in the function. I see the information in the console (console.log) but it is not present in the response by callback(). I always get response of first callback and not of second. I have read about the asynchronous process but I don't achieve fix the issue. Do you know what is the change to improve the code?

The code is the next:

var AWS = require('aws-sdk');
var iam = new AWS.IAM();
var s3 = new AWS.S3();
exports.handler = (event, context, callback) => {
    var params1 = {};
 iam.listUsers(params1, function(err, data) {
   if (err)
    console.log(err, err.stack);
   else
    console.log(data);
    callback(null, data.Users);
 });
 var params2 = {};
 s3.listBuckets(params2, function(err, data) {
   if (err)
      console.log(err, err.stack);
   else
      console.log(data);
      callback(null, data.Buckets);
 });
};

Thanks in advance.

3
do you want to return both results?mostafazh
Yes, I want both results: iam users and s3 buckets. In the future I want to add: instances, security groups, subnet, etc.Arsenio Aguirre
you could also use Python, Java or C# to write your AWS Lambda function. Might be easier if you are already good at one of those.mostafazh

3 Answers

4
votes

Since AWS Lambda now supports node 8, an example code can be found below:

const AWS = require('aws-sdk');
const iam = new AWS.IAM();
const s3 = new AWS.S3();

async function stackoverflow() {
 let params1 = {};
 let params2 = {};

 try {
  // synchronously call each method and store resolved promises. 
  let results1 = await iam.listUsers(params1).promise();
  let results2 = await s3.listBuckets(params2).promise();

  console.log(results1);
  console.log(results2);
 }
 catch(e) {
  console.error(e);
 }
}

exports.handler = (event, context, callback) => {
  stackoverflow();
};
0
votes

This is the ideal case for the Async library or Promise.all if you're using promises. I'll try and make a code sample later when I'm not on my mobile phone, but essentially they'll both let you execute several Async functions and then do one callback.

0
votes

Using Promise.all, you could do something like this:

const AWS = require("aws-sdk");

const iam = new AWS.IAM({apiVersion: "2010-05-08"});
const s3 = new AWS.S3({apiVersion: "2006-03-01"});

exports.handler = (event, context, callback) => {
    const iamParams = {};
    const s3Params = {};
    const promises = [listUsers(iamParams), listBuckets(s3Params)];

    // NOTE: If any of the passed-in promises reject, `Promise.all` asynchronously
    // rejects with the value of the promise that rejected,
    // whether or not the other promises have resolved.
    Promise.all(promises)
        .then(([users, buckets]) => {
            // console.log(users);
            // console.log(buckets);
            callback(null, {
                Users: users,
                Buckets: buckets
            });
        })
        .catch((err) => {
            callback(err);
        });
};

function listUsers(params) {
    return new Promise((resolve, reject) => {
        iam.listUsers(params, (err, data) => {
            if (err) {
                reject(err);
            } else {
                resolve(data.Users);
            }
        });
    });
}

function listBuckets(params) {
    return new Promise((resolve, reject) => {
        s3.listBuckets(params, (err, data) => {
            if (err) {
                reject(err);
            } else {
                resolve(data.Buckets);
            }
        });
    });
}