If you want your Lambda function to interact with resources (e.g., RDS database, EC2 instance) inside a private subnet, you won’t be able to do so by default. The reason for this is that Lambda functions live in an isolated and secured VPC managed by AWS. This is why when you create a Lambda function, you don’t go through any networking configurations (VPC, subnet, ENIs), unlike when creating EC2 instances. Also, you cannot establish a VPC peering connection between the VPC where Lambda functions are run and the VPC where your private resources are located because the former is not accessible to customers.
In this article, I’ll walk you through the process of connecting your Lambda function to a private RDS database instance. This post assumes that you already have your database ready.
STEP -1 Update your Lambda function’s execution role
- In the Lambda Console, under the Configuration tab, select Permissions, then click your function’s role name. This will redirect you to the IAM console.
2. On Permissions, click Add permissions > Attach policies
3. Search for the AWSLambdaVPCAccessExecutionRole managed policy and attach it to the IAM role.
STEP -2 Connect the Lambda function to a VPC
- In the Lambda Console, under the Configuration tab, select VPC, then click the Edit button.
2. Select the VPC where your RDS instance is located.
3. Select one or more subnets in the VPC. Ideally, these subnets should be the same as the ones your RDS instance is using or at least have routes to them.
4. Select a security group that allows traffic between your Lambda function and the RDS instance. You may need to create a new security group or modify an existing one to allow traffic on the correct ports (e.g., port 3306 for MySQL, port 5432 for PostgreSQL).
Lambda functions don’t listen to any inbound traffic, so it’s fine if you don’t set any inbound rules in the Lambda function’s security group. Nonetheless, ensure that the security group permits outbound traffic to the resources your function intends to access. As shown in the screenshot, the same security group is being utilized for both the Lambda function and the RDS database instance.
STEP -3 Update the security group of your database
- Add an inbound rule to your RDS DB instance’s security group with the following settings:
- Choose the appropriate type based on your database engine (e.g., “MySQL” for MySQL on port 3306, “PostgreSQL” for PostgreSQL on port 5432, etc.)
- Port Range: This will be pre-filled based on the selected Type
- Source: Select “Custom” and enter the security group ID of the security group associated with the Lambda function.
Once connected, your Lambda function will lose internet access. This happens due to the fact that AWS Lambda only assigns private IP addresses to ENIs that it creates. Even if your function is connected to a public subnet, your VPC’s internet gateway will still be unable to route traffic between the internet and your function.
To give your Lambda function internet access, you can create a NAT Gateway in the public subnet of your VPC and add an entry to the private subnet’s (the subnet/s connected to your Lambda function) route table. Set the destination to 0.0.0.0/0 and the NAT Gateway as the target to allow outbound traffic from the private subnet to the internet.