AWS Lambda service can't access target group when VPC is enabled - amazon-web-services

I have a target group which has two EC2 instances behind an application load balancer. I'm trying to build a lambda service to monitor EC2 instance healthy status outside of load balancer listener.
this lambda works as expected if VPC is not enabled. once I enabled VPC, then following code will fail:
client = boto3.client("elbv2", region_name=default_region_name)
tg_res = client.describe_target_groups(Names=[self.name])
API describe_target_groups will stuck there until timeout.
this VPC does have internet access and security group inbound/outbound temporary open for all IP.
any hit will be highly appreciated.
==========update==================
From lambda log, timeout happens at:
Starting new HTTPS connection (1): elasticloadbalancing.us-west-2.amazonaws.com
I checked network setting and I'm sure this VPC has NAT configuration.

this issue is solved by assigned another two internal access only subnets.
1) two EC2 instances are behind an ALB. EC2 instances are in subnet, let's say: west-2a-public, west-2b-public. These two subnets are internet facing and can assign public IP.
2) I assigned lambda service into same subnet: west-2a-public and west-2b-public but it doesn't work.
3) I then assigned lambda service into another two subnets: west-2a-private and west-2b-private. These two subnet does have NAT but doesn't have public IP assignment.
I guess the issue the router mapping but I need time to figure out exactly root cause. so far, it works.

You might need to edit your aws lambda function to add VPC support.
You can read more about here

I think the reason for this is the following: First, you need a NAT Gateway to access the Internet for Lambda functions as described here:
https://aws.amazon.com/de/blogs/aws/new-access-resources-in-a-vpc-from-your-lambda-functions/
Internet Access – As soon as you enable this functionality for a
particular function, the function no longer has access to the Internet
by default. If your function requires this type of access, you will
need to set up a Managed NAT Gateway in your VPC (see New – Managed
NAT (Network Address Translation) Gateway for AWS for more
information) or run your own NAT (see NAT Instances).
Second, if you have an EC2 instance or other Service such as a Load Balancer that need to be accessible inbound from the internet then you also need an Internet Gateway. However, it is not possible to assign an Internet Gateway and the NAT to one subnet. Therefore, you need to setup two subnets.
Here is an article describing the correct setup and configurations:
https://marcelog.github.io/articles/aws_lambda_internet_vpc.html

Related

Lambda can't access HTTP endpoint in the same security group

I'm trying to figure out the following:
I have an API service deployed in the default VPC, and I have a ELB configured to access the service.
The ELB is attached to a security group sg-XXXXXXXX1 to restrict inbound traffic (open to all for outbound)
I'm now trying to create a lambda function that can call the API service. (using python requests)
I've tried the following and failed to succeed:
In the configuration > VPC section, I added sg-XXXXXXXX1 as the security group and the 4 default subnets
Added AWSLambdaVPCAccessExecutionRole to lambda role
Created a new security group sg-XXXXXXXX2 (all traffic for inbound and outbound), attached it to lambda, and added sg-XXXXXXXX2 to the inbound list (all traffic) for sg-XXXXXXXX1
Any ideas on what I did wrong? and how I can fix it?
Your ELB is most likely a public ELB (which is the default setting). The ELB DNS will resolve to a public IP address, not a VPC IP address. That means that the traffic going to the ELB will exit the VPC, go out to the Internet, and then back into AWS and into the ELB. When that happens, any association with the Lambda function's security group gets lost. Also, if your Lambda function isn't running in a subnet with a route to a NAT gateway it won't be able to access the Internet at all, so it is just going to timeout and fail when it tries to access the ELB.
To fix this, change the load balancer scheme to private, which will give the load balancer a private VPC IP address, and make it accessible only within the VPC.

AWS VPC Lambda Networking Issue

So I have a very confusing issue that I don't know how to solve. My setup is API Gateway -> Lambda -> IoT Core. I setup the code and it works fine from my IDE. I deploy it to AWS, and my connection to AWS times out.
The Lambda is in a single subnet and the subnet does have a default route to an IGW. I did a test, and the Lambda function can resolve the IP of my IoT endpoint to a public IP (54.x.x.x). But the connect() method times out. My security group for the Lambda function is setup to allow all incoming / outgoing.
What am I missing? Why can't I get to IoT Core from inside a VPC with an IGW configured and seems to be working. Any direction would be greatly appreciated.
UPDATE
After playing around with many different things, I can't identify what exactly I had messed up with my configuration. But following the accepted answer I ended up with the following setup which appears to work for what I need.
subnet-1 10.14.10.0/24 (auto-assign-public=false)
local route ( 10.14.0.0/16 ) and default route=nat-gateway
subnet-2 10.14.20.0/24 (auto-assign-public=false)
local route ( 10.14.0.0/16 ) and default route=nat-gateway
subnet-3 10.14.30.0/24 (auto-assign-public=false)
local route ( 10.14.0.0/16 ) and default route=nat-gateway
subnet-4 10.14.40.0/24 (auto-assign-public=false)
local route ( 10.14.0.0/16 ) and default route=nat-gateway
subnet-5 10.14.200.0/24 (auto-assign-public=true)
local route ( 10.14.0.0/16 ) and default route=igw
nat-gateway
in subnet-5
I don't know if this is what I intended, but this is what I was looking for. A series of subnets that are not publicly accessible, but has an internet connection for access to other AWS services. So my Lambda resources, ECS, etc can sit privately and access what they need.
Thank you everyone for the information.
You should not deploy the Lambda function to a public subnet (that's the subnet with the default route to the IGW). It won't work the way you want it to work. The Lambda function doesn't have, and cannot have, a public IP so cannot route to the internet via the IGW.
If the Lambda needs to be in VPC, then move it to a private subnet and make sure that the private subnet has a default route to a NAT (or NAT gateway) in a public subnet. Or deploy the Lambda function outside of VPC completely, if that's viable.
More information at:
Why can't Lambda in public subnet reach the internet?
Why do we need private subnet in a VPC?
When you say "I did a test, and the Lambda function can resolve the IP of my IoT endpoint to a public IP (54.x.x.x)" Do you mean DNS resolution, or you've checked this with a actual network traffic.
In either case, you can turn VPC Flow Logs for your VPC, and try again. The flow log will identify whether SGs or NACLs are blocking your traffic.
Remember also that Lambda's cannot exists in a public subnet, they have to reside in private subnets, and use NAT GW on public subnets to connect to the internet.
I encountered the same issue. Thankfully, AWS has automated this process and it's only a few clicks but sadly an extra $$$/month (about $30 to start).
You need to create a VPC group that has both public and private subnets. For my case, I was accessing a RDS database to then build email templates and fire off these emails via SES.
What did not work:
When I deployed a default VPC on my lambda function, the RDS would work, but the SES would not. The reason being is the SES API has no access to the internet via default VPCs, you need to setup a private subnet to allow for this.
VPC wizard can do this all for you with a few simple clicks, but you're looking at spending about $30/month (CAD) to setup a NAT gateway + any potential data processing charges per GB (read the pricing). For my case, firing a few email templates off it outweighed deploying another ec2 instance and gave me flexibility for scaling without too much on-the-fly configuration.
This link is a good place to get started. How do I give internet access to a Lambda function that's connected to an Amazon VPC?
Follow the VPC wizard hyperlink within that article, and you just need to go to the VPC console and create a VPC, should look something like this (below)
Once AWS works its magic, you need to assign the VPC to your Lambda function, assign the right permissions to your lambda function AND don't forget to configure your security group with the correct inbound rules. In my case I need to add a PostGres rule to access my RDS.
Hope this helps!

How to user vpc endpoint for ELB?

I would like to create a lambda(vpc) which would access resources in vpc and make a request to services(REST API) via public application load balancer. I found out that vpc end point is better solution than creating a nat gateway.
I have created a vpc endpoint for elasticloadbalancing(by following steps at https://docs.aws.amazon.com/vpc/latest/userguide/vpce-interface.html#create-interface-endpoint) and given full access in the policy. I could not find how to access it from the lambda, what would be the URL to make the request?
Edit:
Thanks to John for the info that vpc endpoint is used to connect to ELB API. So Vpc endpoint would not solve our issue.
We have our infra in vpc which includes database(accessible within vpc only) and application servers running behind the ELB. For certain tasks we want to run lambda which will read database(for this reason lambda has to be inside vpc) and make API calls to our application using ELB. Since ELB is accessible from public dns only, lambda is not able to connect to ELB.
I have read that setting up NAT gateway is a solution. Are there other is simpler ways?
Yes, a NAT Gateway would allow the traffic from a private subnet to go out of the VPC and come back in to the Load Balancer's public IP addresses (via its Public DNS Name).
Alternatively, you could create an additional Internal Load Balancer that could accept traffic from within the VPC and send it to the Amazon EC2 instances.

AWS Lambda Function in VPC With Internet Gateway Still Can't access Internet

I have a lambda function that simply does an http.get to http://www.google.com. If I don't have the function behind a VPC, it works fine. The trouble happens when I put it in my VPC.
I know you need to set up an Internet Gateway. I did this. My two subnets are attached to route tables that route 0.0.0.0/0 to this Internet Gateway. Shouldn't that be all I need?
The function still hangs regardless of the Internet Gateway's association. The subnet's security groups allows All Traffic out of 0.0.0.0/0".
According to Grant Internet Access to a VPC Lambda Function that is everything I should need to do.
Edit:
Adding full list of VPC components to be clear.
Created a new VPC (vpc-09*)
Created a new subnet (subnet-05*) point to my new:
route table, (rtb-0b). I see subnet-05* under Subnet Associations. Under Routes, I see Destination 0.0.0.0/0 linked to the Target of
a new NAT Gateway (nat-08*). This NAT Gateway has an Elastic IP Address and a Private IP Address. It resides in the correct Subnet. The status is Available.
Additionally, I created a new Security Group for the Lambda function. This contains one Outbound Rules for "All traffic" with Destination 0.0.0.0/0
As far as I can tell, I've done absolutely everything in that AWS Documentation link to provide my Lambda with internet access. Yet, it still hangs forever when trying to make a request to the outside internet.
You're almost there. The link that you've provided address your issue directly:
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
You're missing this:
Your VPC should contain a NAT gateway or instance in a public subnet.
This means that without a NAT, your Lambdas won't be able to access the internet - even though "they are" in a public subnet. This is how lambda fundamentally works in VPCs.
The exact same link that you provided instructs you on how to create this NAT Gateway alongside your VPCs and Lambdas.
Complementing the answer - on why you would need a NAT Gateway in this scenario - is due to:
... you can use a network address translation (NAT) gateway to enable instances in a private subnet to connect to the internet or other AWS services, but prevent the internet from initiating a connection with those instances...
Extracted from aws docs
Keep in mind: If you need your lambdas to access only the internet - and not any other resource in the same VPC - I recommend to make them non-VPC and then they'll have internet access out of the box - and you won't pay for the cost of NATs.

Hit an EC2 instance in another account from an AWS lambda function

We have a Lambda function in an account and we would like to access an EC2 instance (via HTTP) in another VPC which has a public IP attached. I was wondering what would be the best way to perform this communication. I am new to Lambda and I just got to know of the VPC lambdas. Which CIDRs do I need to open on the Security Group on the EC2 instance? Can I have a specific set of public IPs being picked in the source VPC - this way I can whitelist that range in the SG?
Does VPC peering seem like an overhead for this case or the only possible solution?
It all Depends on your requirements.However, Peering those VPCs is the best way to have the traffic remaining in your trusted Private Subnets which are located in the Internal Trust Boundaries which satisfies Security best practices (Threat/Security Models and Cloud/Network Architecture).
If there is an enterprise policy with strict rules that communication shall not be routed via DMZ/Public Internet and is a must to keep things within the Trusted Boundary of Internal Routes, I don't see any other choice but to go with the VPC peering : https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/peer-with-vpc-in-another-account.html
However, if requirements are less strict and you can use Public Internet to forward your Traffic out via DMZ, it is possible to achieve this with out sacrificing too much of Security (assuming that your EC2 with public IP on other account is providing service over SSL/TLS where your lambda can communicate with it over an Encrypted Communication Channel while validating the EC2's certificate).
This could be achieved by having Lambda associated with an Internal Subnet of your VPC to talk to the EC2 of other account with Public IP. https://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Scenario2.html
Yes, You still can have your Lambda remaining inside the Internal Subnet. But you need a NAT GATEWAY and update the Routing Table for Lambda's Internal Subnet to point to the NAT GATEWAY (which should be assigned with an EIP) i.e. it will subsequently point to your INTERNET GATEWAY. By this you will make sure that your LAMBDA which, located in your private subnet of VPC can talk with outside i.e. with the EC2 instance, located in another account's with a Public IP. Therefore you can whitelist one IP in the SecurityGroups of your EC2 in Other Account which is the EIP of your NATGATEWAY which Lambda or any other Internal Components in that subnet will use to find their way out to the Internet.