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.
Related
I have a lambda function, that has an API Gateway attached to it. It has a publicly accessible IP address and a domain name (Created by the serverless framework). I can access it from the broad internet, from my own browser (and other devices).
The issue is, it seems to be inaccessible from other services on my account, like an EC2 instance. From the mentioned instance, curl google.com works and returns a response, but curl mylink.com times out.
I think this has something to do with VPC setup, but I can't put my finger at it. What might be the issue here?
Update: Using curl --verbose, I found out that while accessed from anywhere else, the IP the API Gateway is leading to is different, than when accessed from within my AWS account. The VPC doesn't seem to matter, I created a new VPC, an EC2 instance inside it, and it still did the same.
Based on the comments.
The issue was caused by the presence of VPC interface endpoint for API Gateway in the default VPC. The VPC interface endpoint for API gateway is used for private API, not public APIs as used be the OP. Subsequently, calls to public API endpoints fail, as explained in AWS blog:
When they’re configured as private, the public networks are not made available to route your API. Instead, your API can only be accessed using the interface endpoints that you have configured.
There are two ways to combat the issue:
disable Private DNS Name option for the endpoint, or
remove the endpoint.
In the OP's case, the second option was used to solve the problem.
The EC2 instance likely lives inside a VPC which doesn't have public internet access (or may but through a load balancer, bastion host, or any myriad of other options).
You'll need to find out which VPC the EC2 instance lives in, and ensure your lambda function has access to it. You can add a function to a VPC by following the documentation
Recently I am trying to use api for trading without much knowing about the theories. And successfully create a working function and deployed it in aws lambda . Now I am trying some another exchanges and their api creation forms have place for ip address .
I tried searching on internet about this, but did not find anything.
I think the request need to send from the ip address.
Can someone tell me how to tackle this problem. Can I simply change something in lambda and do the thing??
Can I simply change something in lambda and do the thing??
You have to setup a VPC with private subnet and a NAT gateway in a public subnet if you don't have such VPC already. Then you associate your lambda function with the private subnet.
This way your lambda function will access the external api using the NAT. The good thing about NAT is that it has static public IP which you can whitelist at your API provider.
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 am looking to assign a static IP to my Lambda which is being invoked via the API gateway. This is required because, the downstream system that i invoke from this lambda accepts web requests only from a Whitelisted IP.
I am successful in achieving this via the VPC that i associate with my lambda. But VPC introduces a bad cold-start time which sometime ranges 12-16seconds. So i am looking for a way to prevent this cold start from the VPC, but at the same time assign a static IP to the lambda.
You will need to:
Create a VPC with an Internet Gateway, a public subnet and a private subnet
Attach the AWS Lambda function to the private subnet
Launch a NAT Gateway in the public subnet and update the Route Table of the private subnet to use the NAT Gateway
The NAT Gateway will use an Elastic IP address (which is a static IP address). All traffic from the Lambda function to the Internet will come from this IP address, which can be used in the whitelist.
You might think that this is a bit of overkill for simply attaching a static IP address, but multiple Lambda function can run in parallel and they could run in multiple Availability Zones. Sending all traffic through the NAT Gateway is the only way to ensure they all have the same IP address. (Or, to be more specific, one IP address per AZ in which the NAT Gateway is launched.)
You can't assign a public/static IP to any Lambda function.
Your only good option is to deploy into a VPC with an Internet Gateway and configure routing from the Lambda's subnet through a NAT which has an Elastic IP. Then your target host can whitelist the Elastic IP.
Also see:
Public IP address for AWS API Gateway & Lambda (no VPC) - Stack Overflow
AWS Lambda functions with a static IP – Matthew Leak – Medium
I agree with the answer by John for having static IP whitelisting part. However, it won't resolve your cold start problem because lambda,if ideal, actually takes a small time to start. So I would recommend you also create a Cloudwatch event to hit lambda periodically to resolve this or write a simple code(either in lambda or somewhere else) which sends an empty request periodically so that cold start problem is resolved. You can view the improvement in X-Ray. This is an overhead but one time process.
To eliminate cold starts, you can use a service like https://lambdawarmer.com to keep a desired number of lambda instances always warm.
It basically uses a bunch of servers to periodically and exactly concurrently hit an endpoint on your lambda to keep a certain number of lambdas always warm.
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.