4

I coded in my local dev environment a node.js function that does several requests to an external url-uri (asynchronously using bluebird and request-promise). It works fine, the function gets the results and save the information into the EC3 database.

The problem comes when I deploy the code (node modules included), and execute it. It has access to the database, but when tries to access to external url-uri the 'request-promise' module gets an 'connect ETIMEDOUT' error.

I did all the AWS indicates to get it, and read and try a all the solutions I found in Stackoverflow, but still having the problem.

https://www.youtube.com/watch?v=AR1nt3iGR5o

The related role that runs the function has the following policies:

AWSLambdaFullAccess - AWSCodeDeployRoleForLambda - AmazonVPCFullAccess - AWSLambdaExecute - AWSLambdaBasicExecutionRole - AWSLambdaVPCAccessExecutionRole - AWSLambdaRole - oneClick_lambda_basic_execution_1535968782861

Function Network Config

Nat getway

Route Table

Could you help me please, or at least give a hint, please?

CODE:

const Promise = require('bluebird');
const Rp = require('request-promise');
const http = require('http');

var httpAgent = new http.Agent();
httpAgent.maxSockets = 15;

var promises = urls.map(function(url){
  return Rp({uri: url.url, pool:httpAgent}).then(function(result){
      url.result = result;
      // Saving space
      delete url.url;
      return url;
  })

});


Promise.all(promises).then(function(results){
    return(processResults(results));
}).catch(Error, function (e) {
    console.error("Error doing Request: ", e);
}).error(function (e) {
    console.error("Unable get info: ", e);
}).then(function(results){
    try{
        product.callback(results);
    }catch (exception) {
        console.error('Error callback: ',exception);   
    }
}).then(function(){
    product.finally();
});

ERROR:

2018-09-28T14:53:48.989Z    efb5493a-c32d-11e8-ae42-f73dec33ca2a    Error doing Request: { RequestError: Error: connect ETIMEDOUT 147.83.184.65:80
at new RequestError (/var/task/node_modules/request-promise-core/lib/errors.js:14:15)
at Request.plumbing.callback (/var/task/node_modules/request-promise-core/lib/plumbing.js:87:29)
at Request.RP$callback [as _callback] (/var/task/node_modules/request-promise-core/lib/plumbing.js:46:31)
at self.callback (/var/task/node_modules/request/request.js:185:22)
at emitOne (events.js:116:13)
at Request.emit (events.js:211:7)
at Request.onRequestError (/var/task/node_modules/request/request.js:881:8)
at emitOne (events.js:116:13)
at ClientRequest.emit (events.js:211:7)
at Socket.socketErrorListener (_http_client.js:387:9)
at emitOne (events.js:116:13)
at Socket.emit (events.js:211:7)
at emitErrorNT (internal/streams/destroy.js:64:8)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickDomainCallback (internal/process/next_tick.js:218:9)
name: 'RequestError',
message: 'Error: connect ETIMEDOUT 147.83.184.65:80',
cause: 
{ Error: connect ETIMEDOUT 147.83.184.65:80
at Object._errnoException (util.js:1022:11)
at _exceptionWithHostPort (util.js:1044:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1198:14)
code: 'ETIMEDOUT',
errno: 'ETIMEDOUT',
syscall: 'connect',
address: '147.83.184.65',
port: 80 },
error: 
{ Error: connect ETIMEDOUT 147.83.184.65:80
at Object._errnoException (util.js:1022:11)
at _exceptionWithHostPort (util.js:1044:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1198:14)
code: 'ETIMEDOUT',
errno: 'ETIMEDOUT',
syscall: 'connect',
address: '147.83.184.65',
port: 80 },
options: 
{ uri: 'http://geoserver.hydsdev.net/geoserver/mhews/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetFeatureInfo&FORMAT=image%2Fjpeg&TRANSPARENT=true&INFO_FORMAT=text%2Fxml&FEATURE_COUNT=50&X=50&Y=50&SRS=EPSG%3A4326&WIDTH=101&HEIGHT=101&QUERY_LAYERS=mhews:ffews_rain_accumulation_15min_opera&LAYERS=mhews:ffews_rain_accumulation_15min_opera&BBOX=0.6319608%2C42.770155%2C0.8319608%2C42.870155000000004&TIME=2018-09-28T17:30:00.000Z',
pool: 
Agent {
domain: null,
_events: [Object],
_eventsCount: 1,
_maxListeners: undefined,
defaultPort: 80,
protocol: 'http:',
options: [Object],
requests: {},
sockets: {},
freeSockets: {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: 15,
maxFreeSockets: 256,
'http:': [Object] },
callback: [Function: RP$callback],
transform: undefined,
simple: true,
resolveWithFullResponse: false,
transform2xxOnly: false },
response: undefined }

Cheers.

NormaN
  • 71
  • 9
  • 2
    Is the Lambda function configured to run inside your VPC? – Mark B Sep 27 '18 at 18:39
  • Yes, it runs, it writes logs, it access to the EC3 database, but fails when tries to do a http request to get an XML file. – NormaN Sep 28 '18 at 07:22
  • https://aws.amazon.com/premiumsupport/knowledge-center/internet-access-lambda-function/ – Mark B Sep 28 '18 at 10:51
  • Thanks @MarkB, I have already read and followed these steps (both videos), but still stuck not having access out and getting ETIMEDOUT. Will do it again and try to figure out whats wrong. If today it doesn't work out I will not use Lambda functions... I thought it should be easy to use server less functions... at least AWS shows as it is... but it isn't. – NormaN Sep 28 '18 at 11:05
  • Where are you downloading the XML file from? If this is an external server make sure that you have the outbound rules on your security group to allow traffic – Rajesh Sep 28 '18 at 14:05
  • Hi @Rajesh ! Outbound security group rules is Ports: All Destination: 0.0.0.0/0. Thanks for your concern. – NormaN Sep 28 '18 at 14:40
  • Can you post the piece of code that is making the HTTP request and also if possible the detailed error. – Rajesh Sep 28 '18 at 14:58
  • @Rajesh , you got it. Code works in my local environment, and server that gives the XML is in another place. – NormaN Sep 28 '18 at 15:20
  • Does the provider have any IP whitelisting that is allowing your requests from local machine but since the IP from your Lambda is different its timing out. Alternatively try increasing the timeout in your code to see if that works as well. Please do have a look at : https://github.com/request/request/issues/636 – Rajesh Sep 28 '18 at 15:44
  • Finally I fixed the problem. Don't know why but into 'request-promise' options object I have to put: headers: {'User-Agent':'request' } . Thank you very much @Rajesh! – NormaN Oct 01 '18 at 08:44

1 Answers1

0

Finally I fixed the problem. Don't know why but into 'request-promise' options object I have to put: headers: {'User-Agent':'request' } . Thank you very much @Rajesh!

NormaN
  • 71
  • 9