AWS Lambda: Call another REST API outside VPC - amazon-web-services

I have a AWS Lambda function written in C# with a HTTP API Gateway to expose the lambda function.
When I try to invoke another endpoint via httpPost in c#, the lambda logs doesn't display any logs and the request via POSTMAN to the API Gateway returns Service Unavailable.
Should I enable CORS or anything else? I tried to enable CORS but the result still the same.
Can someone help me, please?

AWS Lambda functions running inside a VPC are never assigned a public IP address. So by default they can't connect to anything outside of the VPC. The only way to provide access to resources outside the VPC is to either place the Lambda functions in private VPC subnets with a route to a NAT gateway, or to create VPC endpoints for those services the Lambda function needs to connect to.

Related

How can I troubleshoot connectivity issues between AWS resource types that are not included in the Reachability Analyzer tool? (e.g. Lambda functions)

I have a Lambda function deployed into a public subnet in a VPC and I’m trying to connect to a Lambda function outside of a VPC and I’m running into connectivity issues.
I believe the security group settings and IAM policies will permit the connection, but I'm not sure if there's an issue with connecting to an out-of-VPC Lambda from an in-VPC one.
Is there a tool in AWS Console, AWS CLI or anywhere else that I can use to troubleshoot where the connection is failing? I’ve used the Reachability Analyzer before but it only works on a handful of resource types like EC2 instances.
I've tried invoking the out-of-VPC Lambda from inside my in-VPC Lambda, but the request doesn't work and I don't see any helpful information about what happened. I tried running the Reachability Analyzer, but it doesn't allow you to test if Lambda functions are reachable.
I was expecting the request to work, but I'm not sure if I need to configure a VPC interface endpoint because I'm connecting from an in-VPC Lambda to an out-of-VPC Lambda.
I’m new to networking and would appreciate any help.
I have a Lambda function deployed into a public subnet in a VPC and I’m trying to connect to a Lambda function outside of a VPC and I’m running into connectivity issues.
The Lambda function in the VPC never gets a public IP assigned to it. So it can't connect to anything outside of the VPC. It can't use the Internet Gateway attached to the public subnet because it doesn't have a public IP.
By "connect to a Lambda function outside of a VPC" what you are really doing is connecting to the AWS API outside of the VPC. You never "connect" to a Lambda function, because Lambda functions aren't running and just sitting around idle waiting for your request. Lambda functions don't really exist until a request comes in to the AWS Lambda Invoke API, at which point AWS spins up an instance of the Lambda function and passes it the invocation payload.
To fix this connectivity issue, you either need to create an AWS Lambda VPC Endpoint in your VPC, to handle requests to the Lambda API originating in your VPC. Or you need to move the VPC Lambda function to a private subnet, with a route to a NAT Gateway. Lambda functions in private subnets can access things outside the VPC by having their requests routed through the NAT Gateway.
I was expecting the request to work, but I'm not sure if I need to configure a VPC interface endpoint because I'm connecting from an in-VPC Lambda to an out-of-VPC Lambda.
That's not how VPC Interface Endpoints work. The entire purpose of VPC Interface Endpoints is to allow a resource inside your VPC to access part of the AWS API that exists outside the VPC. A VPC Interface Endpoint will absolutely allow your Lambda function running in the VPC to access the Lambda Invoke API, in order to trigger an execution of your out-of-VPC Lambda function.

Calling a private APIGateway Fronted non-VPC Lambda From within a VPC

Given an AWS Lambda that does not need access to resources within a VPC, the well architected serverless lens recommends not putting the function in a VPC.
However, my Lambda will sit behind an APIGateway to facilitate a REST endpoint that needs to be accessed by servers that do sit within a VPC.
How can a VPC-less Lambda sit behind an APIGateway that itself is accessible within a VPC?
I would prefer that my APIGateway not be exposed to the public internet, therefore instantiating a public APIGateway and calling that public IP address from within my VPC via Nat gateway is not an acceptable solution.
Thank you in advance for your consideration and response.
Invoking an AWS Lambda function will always be done via the public AWS API. It doesn't matter if the Lambda function is configured to run in the VPC once it is invoked, it still has to be invoked via the public AWS API.
AWS Lambda functions do not sit running idle in your VPC waiting for an invocation request to come in. The whole point of Lambda functions is that they do not exist at all until they are needed to process a request, at which point the AWS infrastructure creates an instance of your function, and then passes it the request info to process.
If you add an AWS Lambda function to your VPC, all that does is attach an ENI from your VPC to the Lambda function at the time it is executing, so that it can use the network connection provided by that ENI to access resources inside your VPC.
The API Gateway service itself also does not run inside your VPC. Both API Gateway and Lambda exist outside your VPC, and API Gateway will have no problems accessing the public AWS API to invoke a Lambda function.
When you make your API Gateway VPC only, the API Gateway service (servers) still exists outside the VPC, it just makes the API Gateway accessible at a private address inside your VPC, via a network gateway to the API Gateway service.

AWS Lambda function timing out on calling aws service

I have a lambda function which has the following logic in the handler:
log.info("about to get caller identity..")
caller_identity = boto3.client("sts").get_caller_identity()
log.info(caller_identity)
When I run this lambda function, it times out with the following error:
botocore.exceptions.ConnectTimeoutError: Connect timeout on endpoint URL: "https://sts.amazonaws.com/"
Why is my lambda function not able to reach STS service?
Thanks!
This was the result of the Lambda being associated to a VPC in a private subnet with no way to communicate to the internet.
It is important that when using VPC configuration the Lambda is located in a subnet with the means to communicate with the internet such as a NAT. Without this your Lambda cannot communicate to the internet.
If you're trying to reach an AWS service you can check whether a VPC Endpoint is supported for the service to remove the need for internet connectivity.

Does private link work for a lambda function?

I have a ECS fargate container running inside a private VPC which doesn't have internet access. It needs to invoke a lambda via AWS SDK. Based on my understanding, AWS creates a default public endpoint for the lambda and when I call invokeLambda method the traffic will always go to internet. If my understanding is right, that means my Fargate container won't be able to call the lambda. Is it right?
If it is right, what is the alternative solution is? The goal is that the traffic won't go to internet in any chance.
Can I create a private link endpoint for my lambda?
Or create a API gateway with VPC endpoint which connects to lambda?
If my understanding is right, that means my Fargate container won't be able to call the lambda. Is it right?
Yes. Without NAT gateway or instance, you won't be able to directly invoke the lambda function from private subnet.
Can I create a private link endpoint for my lambda?
Sadly no. There are not VPC interface endpoints for lambda.
Or create a API gateway with VPC endpoint which connects to lambda?
Yes, this should be possible by creating private API gateway. The private API would be only accessible from within your VPC. But API gateway to lambda will still probably go over the internet.
The Security Overview of AWS Lambda whitepaper writes:
Invocations from Amazon Kinesis and DynamoDB streams, SQS queues, Application Load Balancer,and API Gateway follow the request-response path
For request-response invocations, the payload passes from the API caller—such as AWS API Gateway or the AWS SDK—to a load balancer, and then to the Lambda invoke service. This service identifies an execution environment for the function, and passes the payload to that execution environment to complete the invocation. Traffic to the load balancer passes over the internet, and is secured with TLS.

AWS Apigateway does have any static IP address

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.