AWS lambda cannot access DynamoDB after being placed in a private subnet? - amazon-web-services

As the title suggests, I placed my Lambda function in a private subnet and now It cannot access or timeout when scanning the DB. Prior to this, it could access and scan the DB. What should I do?

Your DynamoDB resources are not in your VPC. Since you've configured your Lambda functions to connect to your VPC, you need to setup a NAT Gateway or NAT Instance to allow your private resources to access the internet. As the docs state:
AWS Lambda uses the VPC information you provide to set up ENIs that
allow your Lambda function to access VPC resources. Each ENI is
assigned a private IP address from the IP address range within the
Subnets you specify, but is not assigned any public IP addresses.
Therefore, if your Lambda function requires Internet access (for
example, to access AWS services that don't have VPC endpoints), you
can configure a NAT instance inside your VPC or you can use the Amazon
VPC NAT gateway. You cannot use an Internet gateway attached to your
VPC, since that requires the ENI to have public IP addresses.
AWS Lambda Doc

Validate the following:
The route table for the Lambda has a NAT Gateway for internet traffic that resides in public subnet.
DynamoDB Gateway endpoint exists? Check its policy to ensure that it is not limited to specific sources
Outbound access is allowed via the security group and NACL

Related

AWS Lambda can not access Stripe service? [duplicate]

I've followed the tutorial here to create a VPC with public and private subnets.
Then I set up an AWS lambda function inside the public subnet to test if it could connect to the outside internet.
Here's my lambda function written in python3
import requests
def lambda_handler(event, context):
r = requests.get('http://www.google.com')
print(r)
The function above failed to fetch the content of http://www.google.com when I set it inside the public subnet in a VPC.
Here's the error message:
"errorMessage": "HTTPConnectionPool(host='www.google.com', port=80):
Max retries exceeded with url: / (Caused by
NewConnectionError(': Failed to establish a new connection: [Errno 110]
Connection timed out',))", "errorType": "ConnectionError",
I don't understand why.
The route table of the public subnet looks like this:
The GET request to http://www.google.com should match igw-XXXXXXXXX target. Why can't the internet-gateway(igw) deliver the request to http://www.google.com and get back the website content?
This article says that I must set the lambda function inside the private subnet in order to have internet access.
If your Lambda function needs to access private VPC resources (for
example, an Amazon RDS DB instance or Amazon EC2 instance), you must
associate the function with a VPC. If your function also requires
internet access (for example, to reach a public AWS service endpoint),
your function must use a NAT gateway or instance.
But it doesn't explain why I can't set the lambda function inside the public subnet.
Lambda functions connected to a VPC public subnet cannot typically access the internet.
To access the internet from a public subnet you need a public IP or you need to route via a NAT that itself has a public IP. You also need an Internet Gateway (IGW). However:
Lambda functions do not, and cannot, have public IP addresses, and
the default route target in a VPC public subnet is the IGW, not a NAT
So, because the Lambda function only has a private IP and its traffic is routed to the IGW rather than to a NAT, all packets to the internet from the Lambda function will be dropped at the IGW.
Should I Configure my Lambda Function for VPC Access?
If your Lambda function does not need to reach private resources inside your VPC (e.g. an RDS database or Elasticsearch cluster) then do not configure the Lambda function to connect to the VPC.
If your Lambda function does need to reach private resources inside your VPC, then configure the Lambda function to connect to private subnets (and only private subnets).
NAT or Not?
If the Lambda function only needs access to resources in the VPC (e.g. an RDS database in a private subnet) then you don't need to route through NAT.
If the Lambda function only needs access to resources in the VPC and access to AWS services that are all available via private VPC Endpoint then you don't need to route through NAT. Use VPC Endpoints.
If your Lambda function needs to reach endpoints on the internet then ensure a default route from the Lambda function's private subnets to a NAT instance or NAT Gateway in a public subnet. And configure an IGW, if needed, without which internet access is not possible.
Be aware that NAT gateway charges per hour and per GB processed so it's worth understanding how to reduce data transfer costs for NAT gateway.
Best Practices
When configuring Lambda functions for VPC access, it is an HA best practice to configure multiple (private) subnets across different Availability Zones (AZs).
Intermittent Connectivity
Be sure that all the subnets you configure for your Lambda function are private subnets. It is a common mistake to configure, for example, 1 private subnet and 1 public subnet. This will result in your Lambda function working OK sometimes and failing at other times without any obvious cause.
For example, the Lambda function may succeed 5 times in a row, and then fail with a timeout (being unable to access some internet resource or AWS service). This happens because the first launch was in a private subnet, launches 2-5 reused the same Lambda function execution environment in the same private subnet (the so-called "warm start"), and then launch 6 was a "cold start" where the AWS Lambda service deployed the Lambda function in a public subnet where the Lambda function has no route to the internet.
You can make a lambda function access the public internet from within your VPC, you just need to make sure you really need it.
For accessing resources external to AWS such as Google API (like OP's example) you do need a Public IP. For other cases like RDS or S3 you don't need Public IP, you can use a VPC Endpoint, so communication between your Lambda and the desired AWS Service doesn't leave AWS network.
By default some AWS Services are indeed reached via public internet, but it doesn't have to be.
[EDIT]
Someone was concerned about scalability in the comments, but they missed this from AWS Docs:
"Multiple Lambda functions can share a network interface, if the functions share the same subnet and security group"
Also, you must have a Public IP for reaching Public Internet, whether you're using Lambda, EC2, ECS, even if you use a NAT Gateway it needs an Elastic Public IP if you want to reach the public internet through it.
Solution
To do that, you need to assign Elastic Public IPs to the Network Interfaces for each subnet linked to your lambda. First let's figure which subnets and security groups are linked to your lambda:
Next, go to EC2 Service, find the Public IPs menu under Network & Security. Allocate one IP for each subnet (in the example above there are two subnets).
Go to Network Interfaces menu, find the network interfaces attached to your lambda (same subnet and security group).
Associate the Public IPs in the actions menu for each one:
That's it, now your Lambda can reach out to public internet.

AWS lambda VPC cannot reach internet with IG attached

I have an AWS lambda function that makes a request to the internet. When it makes the request with NO VPC, it's ok, but when I add it to the VPC, it stops working. I've attached an Internet Gateway to the VPC and created a NAT Gateway with RT to use outbound 0.0.0.0/0, but it stills not working.
With the 15seconds timeout, it's always throwing TO.
Could you please help me?
I've already followed these sites:
https://gist.github.com/reggi/dc5f2620b7b4f515e68e46255ac042a7
http://derpturkey.com/lambda-vpc-and-internet-access-configuration/
Everything seems to be well configured.
Lambda configuration
Route Table configuration
IGW attached to VPC
There are three ways to grant Internet access to an AWS Lambda function:
Do not assign it a VPC, or
Assign it to a VPC and attach an Elastic IP Address to the ENI (Elastic Network Interface) that is created in the VPC, or
Assign it to a private subnet in a VPC and use a NAT Gateway to grant the private subnet access to the Internet
If you have already verified the network configurtions like VPC setup, Subnets, Route Table, IG/NAG gate way. And associated the Lambda with current subnet and security groups.
Then the last thing to verify would be:
For Lambda functions to work into custom or User Defined VPC, Adding Lambda to the VPC would require AWSLambdaVPCAccessExecutionRole in addition to AWSLambdaBasicExecutionRole.
Ensure that the associated role has the above permissions.
Source:
https://docs.aws.amazon.com/lambda/latest/dg/vpc-rds-create-iam-role.html

How do I configure a NAT for use with my Lambdas that already have an Internet Gateway for S3 access?

My setup is:
S3 (website) -> API Gateway -> Lambda -> RDS
-> S3 (configuration)
-> Shopify
-> Transactional Mail
I have an Internet Gateway set up to allow access to my S3 configurations and I need to hook up a NAT to allow me to make my calls out to 3rd parties. I've attempted to only use the NAT (per this question) by changing my Routing Table entry for 0.0.0.0/0 -> {my NAT}, but that just results in not being able to access my S3 configuration bucket.
Any help would be greatly appreciated!
Edit: To be clear I've read the documentation, what I'm having issues understanding is the relationships between the Security Group my Lambdas and RDS share, and the Subnets they're associated with.
When I configure my lambda to be part of the security group my RDS instances is in, I need to associate it with at least 2 subnets... Should those be new subnets, and not the ones associated with my RDS instances? AKA does a lambda need to share a subnet with an RDS in order to access it?
If the Lambda function only needs to access VPC resources and S3, then the easiest way to configure this is to add an S3 Endpoint to your VPC. If your Lambda function needs to access VPC resources plus other resources besides S3 and DynamoDB (the only 2 services that currently support VPC endpoints) then your Lambda function has to be in a private subnet with a NAT Gateway.
Instances in a public subnet have the option of having a public IP address, but it isn't a requirement. Lambda functions in a VPC do not ever get public IP addresses, which is why Lambda functions inside a VPC have to be in a private subnet with NAT gateway in order to have Internet access.
The only time Lambda functions get a public IP is when they are not in a VPC at all. In that instance they can access anything except resources in your VPC.
A note about your "same security group" comment: Being in the same security group does not allow resources to access each other. The Lambda function needs to be in a security group that the RDS security group has granted access to. Regarding subnets, the Lambda simply needs to be in any subnet in the same VPC, it does not need to be in the same subnet as the RDS instance.

KMS decrypt works locally but not from within EC2 instance

I am trying to decrypt a file that is stored inside an S3 bucket using KMS. Within an EC2 instance, I am able to retrieve this file from S3, but when I try to decrypt it using KMS, I get the following error:
HTTPSConnectionPool(host='kms.us-east-1.amazonaws.com', port=443): Max retries exceeded with url: / (Caused by ConnectTimeoutError(, 'Connection to kms.us-east-1.amazonaws.com timed out. (connect timeout=60)'))
I am however able to decrypt this file successfully from my local machine. Does anyone know why this may be?
If additional info is required, I would be happy to provide it :)
When you enable VPC for your Lambda AWS shows you following message -
When you enable VPC, your Lambda function will lose default internet access. If you require external internet access for your function, ensure that your security group allows outbound connections and that your VPC has a NAT gateway.
So make sure your lambda has access to internet with correct security groups and NAT gateway.
Also note having IG for your subnet is not sufficient. You need to have a NAT instance or gateway and a route from your subnet to that gateway in route table for lambda to have internet access associated to a custom VPC.
AWS Lambda uses the VPC information you provide to set up ENIs that allow your Lambda function to access VPC resources. Each ENI is assigned a private IP address from the IP address range within the Subnets you specify, but is not assigned any public IP addresses. Therefore, if your Lambda function requires Internet access (for example, to access AWS services that don't have VPC endpoints, such as Kinesis), you can configure a NAT instance inside your VPC or you can use the Amazon VPC NAT gateway. You cannot use an Internet gateway attached to your VPC, since that requires the ENI to have public IP addresses.
Important :
If your Lambda function needs Internet access, do not attach it to a public subnet or to a private subnet without Internet access. Instead, attach it only to private subnets with Internet access through a NAT instance or an Amazon VPC NAT gateway.
Source : http://docs.aws.amazon.com/lambda/latest/dg/vpc.html
One case can be that you are connecting to s3 bucket using VPC endpoint and not have an internet connection.
If this is the case then you have to enable internet connectivity either via NAT or putting your instance in a public subnet.

Putting both Lambda and RDS in default VPC behind an API Gateway?

I am trying to have an architecture with:
Route53 <-> API gateway <-> Lambda <-> RDS and DynamoDB.
I am confused about some networking aspects here!
From most of the documentation, what I understand is that Lambda is by default launched in default VPC and can access internet from there but no resources inside a "VPC". And this 2nd VPC (in quotes) refers to non-default VPCs in most discussions. But what is not clear is what if I placed the Lambda and RDS both in default VPC, lambda in a public subnet with --vpc-config info and RDS in a private subnet, will my Lambda have the internet connection?
Even when everything is in default subnet, should I put my lambda function in to a private subnet with Internet access through an Amazon VPC NAT gateway?
I know it is a theoretical question - documents are confusing me by not explicitly mentioning what cannot be done!
From most of the documentation, what I understand is that Lambda is by
default launched in default VPC and can access internet from there but
no resources inside a "VPC".
That is incorrect. By default Lambda is not launched in a VPC at all. Or if it is in a VPC it is in one that you cannot see because it doesn't exist in your AWS account.
what if I placed the Lambda and RDS both in default VPC, lambda in a
public subnet with --vpc-config info and RDS in a private subnet, will
my Lambda have the internet connection?
No, your Lambda function will not have internet access, even in a public subnet. This is because it is never assigned a public IP address. Once you place a Lambda function inside a VPC you have to have a NAT gateway in order to for the Lambda function to access anything outside the VPC.
Even when everything is in default subnet, should I put my lambda
function in to a private subnet with Internet access through an Amazon
VPC NAT gateway?
Yes, that is the correct way to provide a Lambda function with access to both a VPC and resources that exist outside the VPC.
Also note that DynamoDB (and the AWS API) does not run in your VPC. So if you place a Lambda function inside your VPC that needs to access DynamoDB, or anything else that is accessed via the AWS API, you will have to add a NAT gateway to the VPC.
Note that the "Default VPC" is the term for a the VPC that is setup for you when you first create your AWS account. You can see this VPC in your account in the VPC service console. Aside from it being created for you with default settings, you should just think of this as another VPC in your account. The Default VPC is not used by Lambda when you don't specify a VPC, and it is not used by other services like DynamoDB that exist outside your VPC network.