I am building a webserver with AWS Lambda and I need a public IP address that I can call to request the Lambda function. My users need to put this IP address as an A record into their DNS.
Is it somehow possible, for example, to associate an Elastic IP to a single Lambda function for incoming traffic? Maybe through a load balancer?
For the outgoing traffic I have my NAT and Internet Gateways, which are working fine.
You have 2 choices that can provide this functionality:
API Gateway - This is made for traditional API calls, you will need to create a custom domain mapping to your API within AWS for each domain that will use the API Gateway.
Application Load Balancer - You can use an ALB to have your Lambda as a target for all requests. However, without path based pattern matching be aware that all requests will arrive at the same Lambda.
Both of the above will require that the subdomain is mapped by a CNAME rather than an A Record. This is because both of these domains recycle IP addresses on an infrequent basis.
If you absolutely must have the record resolve to an IP you would need to use an NLB in front of you ALB. The NLB supports a static IP per subnet, the ALB would then become its target through IP mapping and an existing AWS service. If you can use CNAMEs then you do not need to do this.
Related
I'm struggling to find a solution that make ALB forward traffic to API Gateway (Ideally private). Below is the flow:
Domain => ALB => API Gateway.
How can we make ALB forward traffic to private API Gateway?
I do not think you can do this reliably. The only way I can think of is to use IP address type in your ALB's target group. This would have to be private IP address of your private API gateway interface endpoint in the VPC.
The problem is that private IP is probably not guaranteed to be static. Thus you should always use DNS name of the gateway, but ALB will not accept the DNS name. It can only take IP address.
So you can try and use the private IP address as target, and if IP changes too much you have to develop custom solution to monitor the IPs and update your ALB target groups.
I have a full AWS HTTPS web service, with all needed components i.e. a VPC containing:
private ec2 instances
autoscaling groups
a load balancer (with a public domain xxxxx.eu-west-1.elb.amazonaws.com , and even an official public domain xxxxx.com )
security groups
All of this works, and I can access from outside the Amazon cloud to xxxxx.com (using my Golang HTTP client code based on "net/http", for example), provided that I put my client IP address in the inbound rules of the security group of my load balancer (I filter IPs because it's a B2B service so I don't want to let anybody come in).
I have also a lambda function, and I would like to access this web service from that lambda function. The problem is, lambda functions don't have stable IP addresses. My request is similar to this one except that I don't want to access an EC2 instance directly (that would be unadvised since the service is scalable), simply access the public service like somebody from outside the Amazon cloud.
Currently, my lambda function can access any website on the Internet, except my HTTP web service. When I access my HTTP web service my Golang lambda client (the same code than above, so it's not a client issue) hangs in this function call, until the lambda timeouts (or my client timeouts if I configure a timeout in the client):
response, err = client.Do(req) // <--- hangs (client is a http.Client)
I tried to apply the recommended solution:
Allow all (0.0.0.0/0) in the inbound rules of the VPC security group. It works, but like I said, I want to eventually filter IPs to allow only specific clients (in addition of my lambda).
Add the lambda function in the VPC (the same VPC that the web service), create a security group for the lambda (with no inbounds rules, all/default outbounds rules), and allow that security group into in the inbound rules of the VPC security group. It doesn't work for some reason.
Is there a solution to do what I want?
Add the lambda function in the VPC (the same VPC that the web
service), create a security group for the lambda (with no inbounds
rules, all/default outbounds rules), and allow that security group
into in the inbound rules of the VPC security group. It doesn't work
for some reason.
You are on the right track here, but unfortunately your public load balancer will be resolved by the Lambda function to its public IP address, which exists outside the VPC. So the Lambda then tries to reach out of the VPC to access the load balancer, at which point the traffic becomes disassociated with the Lambda function's security group.
You have two options:
Add an internal load balancer to your infrastructure, and a Route53 private hosted zone to resolve the domain name to the internal load balancer from within your VPC.
Deploy the Lambda function in VPC subnets that have a route to a NAT Gateway, and allow the NAT Gateway's Elastic IP address in the public load balancer's security group.
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.
I have provisioned an AWS API Gateway and created a Lambda function to connect to an external REST API. The API Gateway & Lambda is not in a VPC so the egress IP address is random. The challenge I have is the external REST API is behind a firewall, which requires the IP address or subnet of the Lambda to be whitelisted.
I have looked at the AWS IP Address page (below), however there is no explicit mention of either API Gateway or Lambda.
https://docs.aws.amazon.com/general/latest/gr/aws-ip-ranges.html#filter-json-file
Has anyone come across this before & found a resolution to it. For the purposes of this solution I cannot put the API Gateway & Lambdas in a VPC.
Any help would be greatly appreciated!
API Gateway seems to be irrelevant to this discussion. If I understand your question, you're trying to make API requests from a Lambda function to a remote API server and you want those requests to originate from a known IP address so that you can whitelist that IP at the remote server.
First thing I would say is don't use IP whitelisting; use authenticated API requests instead.
If that's not possible then use VPC with an Internet Gateway (IGW). Create a NAT and an Elastic IP, launch the Lambda into a private subnet of that VPC, and route the subnet's non-local traffic to the NAT. Then whitelist the NAT's Elastic IP on the remote API server. Examples here and here.
I know that you said you "cannot put [...] Lambdas in a VPC", but if you don't then you have no control over the originating IP address.
It is frustrating that the only way to ensure a Lambda function uses a static ip without a hack is to put the Lambda inside a VPC, create a NAT with an Elastic IP, as many other answers nicely explain.
However, NATs cost around $40 per month in regions that I am familiar with, even with minimal traffic. This may be cost prohibitive for certain use cases, such as if you need multiple dev/test/staging environments.
One possible workaround (which should be used with caution) is to create a micro EC2 instance with an elastic IP (which gives the static IP address), then your choice of proxy/routing so you can make HTTP calls by tunnelling from the Lambda function through the EC2 instance. (e.g. SSH from Lambda function into EC2 instance then CURL from EC2 to the endpoint which is protected by an allowlist)
This is a few extra hoops to jump through and could introduce security vulnerabilities which should be mitigated (e.g. Beware storing SSH keys or passwords inside a Lambda function, ensure Security Groups are tight) but I wanted to post this as a possible workaround for any devs who need a cost effective workaround for a requirement to connect to an endpoint which enforces allowlist rules.
I have an aws api gateway which has a custom domain.
I have to access one of client's api from AWS api gateway.
Those api's will be accessible based on IP address.
If I want to access those api's from aws, I need to know the Ip address of my AWS apigateway.
But I am not sure where I can get this.
Any possibilities to get the static IP address of AWS apigateway?
Unfortunately the API Gateway doesn't support this scenario of invoking an IP-whitelisted API directly. Basically any AWS instance can be used to make the API call and there's many IPs that AWS is using for this.
There are some ways around this, depending on your situation;
If the server you are reaching is within your own VPC, you could create a VPC link (with NLB) and circumvent the IP-whitelist issue. This solution only works for resources within your control.
If the server is external and is expecting a static IP, your best solution is to make your call from within a VPC. To make sure you have a static public IP you can use an elastic IP and a NAT Gateway in your VPC (more info here).
To invoke the external API triggered from the API Gateway you can use a Lambda but because of the VPC a cold start will be quite slow, >10s. To make sure the API will be responding fast you can use an EC2 instance or ECS service on Fargate.
After you clarified your requirements in the comments above it appears that you need your AWS Lambda function, which is being triggered by API Gateway, to appear to a third party as if it has a static outgoing IP address.
The solution to this is to configure your Lambda function to run in your VPC, in a private subnet of your VPC that has a route to a NAT Gateway. Then all outgoing connections from the Lambda function which access resources outside your VPC will use the NAT Gateway's static IP address.