AWS Lambda NodeJS Connect to RDS Postgres Database
Asked Answered
D

1

13

I'm trying to test connectivity between my Lambda and an RDS instance. I have them both on the same private subnets with all ports open in the security group. When I trigger the Lambda I do see a connection opened on the RDS instance. However, the Lambda times out after 4 minutes, 40 seconds. The PG environment variables are set in the Lambda configuration.

const { Client } = require('pg');
const client = new Client();

var hello = [
  { name: 'test', description: 'testerface' }
];

exports.handler = async (event, context, callback) => {
    // Postgres Connect
    client.connect();
    const res = client.query('SELECT $1::text as message', ['Hello world!']);
    console.log(res);
    var response = {
        "statusCode": 200,
        "headers": {
            "Content-Type" : "application/json"
        },
        "body": JSON.stringify(hello),
        "isBase64Encoded": false
    };
    callback(null, response);
};

How can I get back the response from the connection in the Lambda's logs - or even better in the response body?

Detriment answered 30/12, 2018 at 22:58 Comment(0)
F
25

You need to handle the client connection better. That means catching any exceptions that the client may through and releasing the connection properly. This code will return the output of the query to the response body:

const pg = require('pg')
const pool = new pg.Pool()

async function query (q) {
  const client = await pool.connect()
  let res
  try {
    await client.query('BEGIN')
    try {
      res = await client.query(q)
      await client.query('COMMIT')
    } catch (err) {
      await client.query('ROLLBACK')
      throw err
    }
  } finally {
    client.release()
  }
  return res
}

exports.handler = async (event, context, callback) => {
    try {
      const { rows } = await query("select * from pg_tables")
      console.log(JSON.stringify(rows[0]))
      var response = {
          "statusCode": 200,
          "headers": {
              "Content-Type" : "application/json"
          },
          "body": JSON.stringify(rows),
          "isBase64Encoded": false
      };
      callback(null, response);
    } catch (err) {
      console.log('Database ' + err)
      callback(null, 'Database ' + err);
    }
};
Fillet answered 31/12, 2018 at 1:19 Comment(2)
Why use pool in the lambda? Should we use simple client.? Lambda itself is concurrent. Isn't creating a pool is useless here?Nittygritty
It's not exactly correct, lambda will remain active and the handler will be invoked for each subsequent call. Context (parameters, variables outside of handler) will not get reinitialised when the handler gets invoked. Also if you open/connect inside the handler, your connection can remain open to db, essentially consuming all resources on RDS. Unfortunately, you either need to configure the pool and limit the ceiling, or throttle lambda itself.Chromogen

© 2022 - 2024 — McMap. All rights reserved.