Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS Lambda using Node Js gives "connect ETIMEDOUT" on http.request()

I have written lambda function that retrieve s3 Url whenever any new object created on s3 bucket. after retrieve s3Url this lambda make request to my server over REST Call.

I observed cloud watcher. It failed to send request to my Server I don't want to use external packages in my lambda & i want to make it lightweight that's why i used nodeJ's https.

Here is my Lambda code

 exports.handler =  (event,context,callback) => {
  // Extract S3 Url and id From S3 object present in event
  const https = require('https');
  let {s3 , awsRegion} = event["Records"][0];
  let {object : {key}, bucket : {name}} = s3;
  let s3URL = `https://${name}.s3.${awsRegion}.amazonaws.com/${key}`;
  console.log("sURL",s3URL);
  let _id = key.split('/')[0];
  console.log("id",_id);
//Making http request to my server
  let body='';
  // the post options
  let optionsPost = {
     host: 'xyz.abc.com', 
    path: '/api/v1/apipath',
    method: 'POST',
    headers: {
    'Content-Type': 'application/json',
    'Authorization': 'XYZ',
    'id' : _id
  }
  };
  const keepAliveAgent = new https.Agent({ keepAlive: true });
  optionsPost.agent = keepAliveAgent;
  let reqPost =  https.request(optionsPost, function(res) {
      console.log("statusCode: ", res.statusCode);
      res.on('data', function (chunk) {
          body += chunk;
      });
      res.on('end', function () {
        console.log("Result", body.toString());
         context.succeed("Sucess")
      });
       res.on('error', function () {
        console.log("Result Error", body.toString());
        context.done(null, 'FAILURE');
        callback(new Error('failure')) // to return error
      });
  });
  reqPost.write(JSON.stringify({ s3Url: s3URL,userName: 'SYSTEM' }));
  reqPost.end();
};

And here is my cloud watcher Error

{ "errorType": "Error", "errorMessage": "connect ETIMEDOUT 34.255.225.41:443", "code": "ETIMEDOUT", "errno": "ETIMEDOUT", "syscall": "connect", "address": "34.255.225.41", "port": 443, "stack": [ "Error: connect ETIMEDOUT 34.255.225.41:443", " at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1107:14)" ] }

like image 951
Ameya Salagre Avatar asked Nov 13 '19 09:11

Ameya Salagre


People also ask

Does AWS Lambda support node JS?

You can now develop AWS Lambda functions using the Node. js 16 runtime. This version is in active LTS status and considered ready for general use.

Does AWS Lambda have internet access by default?

By default, a lambda function is not bounded to a VPC, which enables it to have internet access, but prevents it from accessing resources in a VPC, such as RDS instances.


Video Answer


1 Answers

If you are attempting to access S3 (or any other AWS resource) through the AWS SDK or directly through any HTTP call from a Lambda then either one of two scenarios must be true:

  • Your Lambda is not set up to run in a VPC
  • Your Lambda is set up to run in a VPC, and the VPC is set up with a NAT gateway.

In AWS, VPCs provide a 'public' network and a 'private' network where all resources in the VPC can communicate with other resources in the VPC regardless of which segment they are on. Any resources on the public segment of the VPC will route public-internet bound traffic through the Internet Gateway that is provided on most VPCs out of the box. However, any containers/resources that are set up on a VPC's private segment are firewalled and do not have routing for public internet addresses without installing a NAT.

When you invoke a Lambda function that is configured to run inside a VPC, the container which runs the code is created in the private segment of the VPC. Therefore, without a NAT the Lambda can only access any resources within the VPC through their internal IP addresses/DNS names.

Since all AWS Service resources are generally accessed from their public-facing service domain name (such as from AWS S3), attempts to access them in a Lambda behind a VPC with no NAT gateway will result in your function receiving ETIMEDOUT errors.

This also occurs when using the AWS SDK within a Lambda for the same reasons.

If your function needs to be behind a VPC to access other resources, then you should set up a NAT Gateway on your VPC. More information on how you can do this is found in the AWS Documentation. Otherwise, you should ensure that your Lambda is not set up to use the VPC as running it inside the VPC incurs additional cold-start times latency along with the network connectivity challenges.

like image 77
JayReardon Avatar answered Oct 12 '22 13:10

JayReardon