Issue with invoking lambda from another lambda - node.js

I have 2 Lambda functions that I would like to call directly not through API Gateway. Lambda function A is Calling Lambda B along with queryStringParameters. For some reasons I'm getting this error
{ UnexpectedParameter: Unexpected key 'queryStringParameters' found in params
This is my Lambda A function
var aws = require('aws-sdk');
var lambda = new aws.Lambda({
region: 'eu-central-1'
});
exports.handler = (event, context, callback) => {
var params = {
FunctionName: "function-getStats",
InvocationType: "RequestResponse",
LogType: "Tail",
"queryStringParameters" : { "fn" : "latest_no" }
};
lambda.invoke(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
};
Which is calling Lambda B as below
var AWS = require('aws-sdk');
AWS.config.update({region: 'eu-central-1'});
var ddb = new AWS.DynamoDB.DocumentClient({apiVersion: '2012-08-10'});
exports.handler = (event, context, callback) => {
var fn = event["queryStringParameters"]['fn'];
...
..
//If successful return the following response
console.log("Success", items);
callback(null, {
'statusCode': '200',
'body': JSON.stringify(items),
'headers': {
"Access-Control-Allow-Origin": "*"
},
'isBase64Encoded': false
});
Can someone please advise how to fix this?

In case anyone got the same issue. here's the approach I did
var aws = require('aws-sdk');
var lambda = new aws.Lambda({
region: 'eu-central-1'
});
exports.handler = (event, context, callback) => {
event.queryStringParameters= {"fn" : "latest_no" };
var params = {
FunctionName: "function-getStats",
InvocationType: "RequestResponse",
LogType: "Tail",
Payload: JSON.stringify(event, null, 2),
};
lambda.invoke(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
};

Related

Call a nested function in AWS lambda

I have a AWS Lambda function that checks if a site is online
var http = require('https');
var url = 'https://www.google.com';
exports.handler = function(event, context) {
http.get(url, function(res) {
console.log("Got response: " + res.statusCode);
context.succeed();
}).on('error', function(e) {
console.log("Got error: " + e.message);
context.done(null, 'FAILURE');
});
}
I would like to reboot an EC2 instance if the website is offline.
This is the Lambda function to reboot EC2:
var AWS = require('aws-sdk');
exports.handler = function(event, context) {
var ec2 = new AWS.EC2({region: 'us-east-1'});
ec2.rebootInstances({InstanceIds : ['i-xxxxxxxxxxxxxxx'] },function (err, data) {
if (err) console.log(err, err.stack);
else console.log(data);
context.done(err,data);
});
};
Both functions work.
Now I am trying to call the ec2 reboot function when the https request fails.
I have an extremely limited experience with node.js and aws so I tried many different ways but no result.
Can someone point me in the right direction?
you can invoke a lambda using the invoke function.
function checkWebsite(url, callback) {
https
.get(url, function(res) {
console.log(url, res.statusCode);
return callback(res.statusCode === 200);
})
.on("error", function(e) {
return callback(false);
});
}
var http = require('https');
exports.handler = function(event, context, callback) {
var url = 'https://www.google.com';
checkWebsite(url, (check) => {
if (!check) {
const lambda = new AWS.Lambda();
const params = {
FunctionName: "my-function",
Payload: '{"instanceId":"instance-1233x5"}'
};
lambda.invoke(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
// handle error/ success
// if you return the error, the lambda will be retried, hence returning a successful response
callback(null, 'successfully rebooted the instance')
});
} else {
callback(null, 'successfully completed')
}
})
}
Reference: Nodejs function to check if a website working

Not able to fetch data from dynamodb from lambda function

I am trying to fetch data from dynamodb from my lambda.I have written this code
exports.handler = async (event) => {
// TODO implement
var AWS = require('aws-sdk');
AWS.config.update({region: 'ap-south-1'});
var ddb = new AWS.DynamoDB({apiVersion: '2012-08-10'});
var params = {
TableName: 'my_table',
Key: {
'serial_number': {S: '17AB-574C-C1'}
},
};
ddb.getItem(params, function(err, data) {
if (err) {
console.log("Error", err);
} else {
console.log("Success", data.Item);
console.log(data);
}
});
};
This code works fine when I run locally but I get a null response when I run it on lambda.My lambda has dynamoDbfullAccess policy attached to it. Can anyone tell me what could be the reason?

s3PutObject has stopped working all of a sudden from Lambda

I have this code in my Lambda function
const AWS = require('aws-sdk');
const s3 = new AWS.S3();
exports.handler = (event, context, callback) => {
const bucketName = "dhaval-upload";
let data = {
firstname: event.firstname,
lastname: event.lastname,
email: event.email,
userAgent: event.userBrowser,
userIP: event.userIP
};
let params = {
Body: JSON.stringify(data),
Bucket: bucketName,
Key: event.email
};
s3.putObject(params);
callback(null, { message: event.email});
};
This returns the success callback but does not write the object in s3.
and this was working but now for some reason it does not.
Please Note :- I checked cloudwatch logs and could not find the reason for the issue from it.
may be you can try it like this, you should use callbacks / async to your code
const AWS = require('aws-sdk');
const s3 = new AWS.S3();
exports.handler = (event, context, callback) => {
const bucketName = "dhaval-upload";
let data = {
firstname: event.firstname,
lastname: event.lastname,
email: event.email,
userAgent: event.userBrowser,
userIP: event.userIP
};
let params = {
Body: JSON.stringify(data),
Bucket: bucketName,
Key: event.email
};
// s3.putObject(params);
// callback(null, { message: event.email});
// === it works like this ===
s3.putObject(params, (err, data) => {
if (err) callback(null, err);
else callback(null, { message: event.email });
});
};

DynamoDB, Lambda function / custom module Timeout

I have the following two JS file. My problem is when i call the Calls.js which calls the Archive.js for archiving logs into DynamoDB the request times out.
I have tried out, many things, read about many things, tried in local/AWS environment without luck. What am i missing?
Link1, Link2, Link3, Link4, Link5,
Archive.js
module.exports.archive = archive;
...
function archive(input, callback){
AWS.config.update({
region: "eu-west-1",
endpoint: "http://localhost:8000"
});
var documentClient = new AWS.DynamoDB.DocumentClient({
httpOptions: {
agent: new https.Agent({
rejectUnauthorized: true,
secureProtocol: "TLSv1_method",
ciphers: "ALL"
})
}
});
...
var paramsPUT = {
TableName: "Logging",
Item: {
HashKey: dbID,
archiveEntry: archiveEntry
}
};
...
documentClient.put(paramsPUT, function(err, data) {
if (err) console.log(err);
if (data) console.log(data);
...
callback(data);
});
}
Calls.js
exports.handler(event, context, callback) => {
const archive = require("./..path..").archive;
...
context.callbackWaitsForEmptyEventLoop = false;
...
archive(input, callback);
...
}
I can not reproduce a timeout condition with your code. Your code is talking to an AWS endpoint at http://localhost:8000, so I assume you have DynamoDB local up and running, don't you ? Failling to have local DynamoDB running would cause the timeout.
That being said, I would strongly suggest to refactor your code to use Promise and the new async/await provided by NodeJS 8 instead of passing the Lambda callback around.
Here is the modified code.
const AWS = require("aws-sdk");
async function archive(input) {
return new Promise( (resolve, reject) => {
AWS.config.update({
region: "eu-west-1",
endpoint: 'http://localhost:8000'
});
//use client specific AWS configuration instead of the global one
const documentClient = new AWS.DynamoDB.DocumentClient();
var paramsPUT = {
TableName: "Logging",
Item: {
HashKey: "123",
archiveEntry: input
}
};
documentClient.put(paramsPUT, function (err, data) {
if (err) {
console.log("ERROR " + err);
reject(err);
}
console.log("Returned from DDB " + JSON.stringify(data, null,2));
resolve(data);
});
});
}
exports.handler = async (event, context, callback) => {
const result = await archive("abc");
callback(result);
}
// stuffs to test locally
callback = function (data) {
console.log("callback called with " + JSON.stringify(data,null,2));
}
event = context = {}
exports.handler(event, context, callback);

AWS Node.js Lambda Invoking Lambda Failing

The AWS Lambda.invoke command seems to do nothing for me. It neither throws an error nor returns. I've read tonnes of posts and I think have all the ARN right. But since the 'invoke' never happens, I assume this is an ARN issue? Any ideas?
Code:
var AWS = require('aws-sdk');
AWS.config.region = 'us-east-1';
var lambda = new AWS.Lambda();
exports.handler = async (event) => {
var params = {
FunctionName: 'myfunction',
InvocationType: 'Event',
LogType: 'Tail',
Payload: '{"sample_param": "payload_string"}'
};
lambda.invoke(params, function(err,data){
if (err) {
console.log("Error");
} else {
console.log("Returned: " + data.Payload);
}
});
};
This returns:
ARN / Policies:
Solution, I'm an idiot and didn't use a promise:
exports.handler = async (event) => {
var params = {
FunctionName: 'my_fuction',
InvocationType: 'RequestResponse',
Payload: '{"my_param": "my_value"}'
};
return lambda.invoke(params).promise();
};

Resources