6

I am trying to build a graphQL API with Serverless Framework on AWS-Lambda using Apollo-Server-Lambda etc. I need to use a not publicly available PostgreSQL RDS instance.

I can get lambdas up and running and sending back requests when not in VPC. I can get a Postgres RDS Database up and running and connected to PgAdmin (when in publicly available mode).

The problem is once I make the RDS Postgres 'non public' and try to get all these pieces talking together I fail.

I have tried multitude of different approaches.

This is regularly portrayed as magic. It is wonderfully written https://gist.github.com/reggi/dc5f2620b7b4f515e68e46255ac042a7

I could not get access to Postgres with my lambdas using this. So my first question.

Do I need a NAT gateway for incoming (ingress) api calls to lambdas in a VPC? My current understanding is that maybe I only need a NAT gateway for my lambdas to make outgoing calls to other api's out of aws or things like S3. Is this correct?

Next up. I have made a security group for my lambdas and have added this security group to the inbound list for the security group that was created for RDS. My understanding is this is how the lambdas should gain access to RDS. I have not had such luck. Maybe this is related to public or non public subnets? Maybe this is related to my understanding of the necessity of a NAT?

Basically the only visibility I have been able to get is Lambdas timing out after 20 or 30 seconds depending on my limit when they are trying to connect to postgres in private. Cloudwatch logs reveal nothing else.

Lastly, for now , what is the best way to connect my dev machine to Postgres once it is 'not public'? I have my machines IP listed for inbound TCP/IP to port 5432 to postgres in the RDS security group but that does not seem to give me the access I was hoping for. Do I really need a VPN connected to VPC? Whats the simplest way?

I have done this tutorial with basic alterations for Postgres https://docs.aws.amazon.com/lambda/latest/dg/vpc-rds.html

I have read and considered answers from this question & more Allow AWS Lambda to access RDS Database

I have had many success-full deployments with serverless framework with many variations on serverless.yml config to try these options or else I would show a specific one I thought was failing but this is more broadly that I cant seem to grasp exactly how all these VPC, security groups, routing tables etc are supposed to interact.

Any help greatly appreciated!

Carl Lippert
  • 329
  • 3
  • 9
  • Instead of the `security group for my lambdas`, can you add the subnet CIDR (which is configured for the Lambda) to the inbound rule and try to access it? You don't need a NAT gateway if all your resources (Lambda, RDS etc.) are in a VPC. – krishna_mee2004 Jan 31 '18 at 13:47

2 Answers2

13

Obviously, Lambda needs to be setup to run inside the same VPC, but I'm assuming you already got that.

You need to:

  1. Create a security group (SG) and associate it with the Lambda function.
  2. Now, open the SG associated with the RDS instance (not the one you created above).
  3. Inside the RDS SG, go to "Inbound" tab and click "Edit"
  4. Select "PostgreSQL" in the Type column. In the Source column, select "Custom" in the select dropdown and enter the Lambda SG ID in the input text (if you start typing "sg-", it will show you all your SGs).

Does it work?

Renato Byrro
  • 3,578
  • 19
  • 34
  • Adding the security group that the lambda function belongs to was what I was missing. Is there now way to determine an internal ip range for the lambda function? Regardless, at least this works- – chrismarx May 03 '23 at 16:59
  • Your Lambda can run in any machine from a large pool of hosts. It's impossible to determine the IP address beforehand. Also, when you have concurrent instances running, they could have different IP addresses. – Renato Byrro May 05 '23 at 02:10
  • Right, but if the lambda function is running in a vpc, shouldn't it be a predefined range at least? – chrismarx May 05 '23 at 13:40
  • 1
    Yes, when a Lambda function is running within a VPC, it will be assigned an IP address from the subnet's IP address range (CIDR block) in which it is deployed. Although you can't predict the exact IP address, you can determine the range of IP addresses based on the subnets associated with the Lambda function. – Renato Byrro May 06 '23 at 00:05
  • So oddly enough though, I couldn't get this to work with a cidr block range. Is there any way to log the ip address or run a connection test or something? – chrismarx May 06 '23 at 13:53
  • I suppose so. For instance, on node.js I believe you could use [`os.networkInterfaces()`](https://nodejs.org/api/os.html#osnetworkinterfaces) or [netifaces](https://pypi.org/project/netifaces/) library on Python, for example. I don't think it's going to be of much use, as AWS recycles Lambda containers quite often, and they may spin up on different machines and IP addresses later. – Renato Byrro May 06 '23 at 23:51
2

Make sure your Lambda function is in the VPC, and the security group allows connections from IP addresses within the subnet of the VPC. The amount of available IP addresses is going to affect how many lambda functions can be run concurrently. Also make sure that the Lambda function's role has the ability to describe the VPC (the AWSLambdaVPCAccessExecutionRole policy should do the job for you).