Lambda in a VPC not able to access internet - amazon-web-services

I have a lambda function which is in a VPC, with an internet gateway. The security group connected to the lambda has all the inbound and outbound routes open. The route table is also updated. The lambda is still not able to access the internet. Am I missing anything?

Lambda in a VPC does not have access to internet. You need to setup internet gateway in public subnet and NAT gateway in private subnet with your lambda to be able to access internet. From docs:
Connect your function to private subnets to access private resources. If your function needs internet access, use NAT. Connecting a function to a public subnet does not give it internet access or a public IP address.
Also you need to add permissions to your lambda's execution role to be able to create network interface in VPC:
ec2:CreateNetworkInterface
ec2:DescribeNetworkInterfaces
ec2:DeleteNetworkInterface

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.

Publicly accessible RDS and Lambda with Internet access

I have a lambda function that needs to access RDS and the internet. Everything out there points to having to set up a NAT gateway; the RDS in question is publicly accessible, the lambda is able to connect to it if I allow connections to the RDS from all IPs; however, I would like to avoid that. Is there a way to determine the possible range of IPs to be assigned to a lambda function and whitelist that range in the security group>?
Locate your Lambda into your VPC, private subnet and set the security group for Lambda. After that, add the Lambda security group to the inbound source of the RDS security group. Then, the Lambda will communicate with the RDS privately.
The private subnet should route the target 0.0.0.0/0 to the internet through a NAT gateway where the NAT should locate in the public subnet. Then, the private subnet can connect to the internet safely.

AWS lambda cannot access DynamoDB after being placed in a private subnet?

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

AWS Lambda Function with VPC only works when in Private Subnet

I have been working on integrating an Amazon Lambda function with connection to a RDS for the mySQL DB and an external API. To access the API, there needed to be an internet gateway and then security groups that allowed connection from 0.0.0.0/0.
I have a a public subnet and private subnet. The public subnet routes to the internet gateway but the private subnet routes to a NAT.
This lead me to think that if I ran the Lambda function with the Public subnet, it would connect to the internet. However, every time it timed out. But, when I ran the lambda function from within the private subnet, it worked! So it the NAT seems to work since that is what the private sunet was associated with, but just using the internet gateway does not work.
Does anyone have any explanation for this?
For an Amazon Lambda function to connect to the Internet, ONE of the following is required:
The Lambda function is not connected to a VPC, OR
The Lambda function is connected to a private subnet and there is a NAT Gateway/NAT Instance configured, OR
The Lambda function is connected to a public subnet and an Elastic IP address is assigned to the Elastic Network Interface (ENI) being used by the Lambda function in the subnet
Merely connecting a Lambda function to a public subnet (without an EIP) will not provide Internet access.

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.