Search code examples
amazon-web-servicesaws-lambdaamazon-ecsamazon-vpc

A request from a private subnet to a public subnet


My VPC has two subnets - public and private.

The public subnet contains ECS Fargate Task:

Network mode -> awsvpc
ENI Id -> eni-xxxxxxxxxx
Private IP -> 10.0.0.36
Public IP -> 34.243.XXX.XXX

The private subnet contains a Lambda function.

When I try to connect from Lambda at IP 10.0.0.36 I get the error:

{
  "errorType":"Error",
  "errorMessage":"getaddrinfo ENOTFOUND 10.0.0.36:3000",
  "trace":[
    "Error:getaddrinfo ENOTFOUND 10.0.0.36:3000",
    "at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:66:26)"
  ]
}

how can this be corrected?

PS. Internet access is not required for Lambda.

Addition:

Simplified code of my Lambda:

const http = () => {
    const body = '{"vehicles":[{"id":0,"profile":"driving-car","start":[32.41,34.784],"end":[32.41,34.784]}],"jobs":[{"id":0,"location":[32.41,34.784]},{"id":1,"location":[32.480,34.835]}],"options":{"g":true}}';
    const options = {
        hostname: '10.0.0.36:3000',
        path: '/',
        method: 'POST',
        headers: {
            'Content-Type': 'application/json; charset=utf-8',
            'Content-Length': Buffer.byteLength( body ),
        }
    };
    return new Promise(resolve => {
        const req = require('http' ).request(options, res => {
            res.setEncoding('utf8'); 
            var str = '';
            res.on('data', chunk => str += chunk);
            res.on('end', () => resolve(str));
        });
        req.write(body);
        req.end();
    });
};
exports.handler = async (event) => {
    const response = {
        statusCode: 200,
        body: await http(),
    };
    return response;
};

Solution

  • Making HTTP requests with Node.js shows some sample code as:

    const https = require('https')
    const options = {
      hostname: 'whatever.com',
      port: 443,
      path: '/todos',
      method: 'GET'
    }
    
    const req = https.request(options, res => {
      console.log(`statusCode: ${res.statusCode}`)
    
      res.on('data', d => {
        process.stdout.write(d)
      })
    })
    
    req.on('error', error => {
      console.error(error)
    })
    
    req.end()
    

    I notice that they have listed the port: as a separate field, rather than adding it to the hostname.

    Your code, however, shows:

    hostname: '10.0.0.36:3000'
    

    Try providing the hostname and port as separate fields.