Note: I am NOT asking why a Lambda in a subnet cannot access the public internet.
I would like to host a Lambda function, with the Function URL enabled, in a public subnet and expose it via CloudFront. This is so that the function can be called from the broader internet but also access private resources.
Is this possible?
I have tried creating a very simple Lambda (the default generated by the serverless.AspNetCoreMinimalAPI
template) and uploading to a simple function with Function URL enabled. With just that, I can call the Lambda from (eg) Postman.
The moment I attach it to the public subnet of my VPC I get 502 Bad gateway
even with an Internet Gateway attached to the VPC.
4
Answers
Yes, it is possible. You need to add a NAT Gateway to your VPC and attach it to your public subnet. Then you need to add a route to your route table to route all traffic to the NAT Gateway. You can find more information here: https://docs.aws.amazon.com/lambda/latest/dg/configuration-vpc.html
You can use an API gateway in front of your Lambda, and keep all your ressources in private subnet (to keep them fully secured).
You’ll no longer need a public url for your lambda, the api gateway has mapping routes, so you can use them.
You may add a cloudFront to the api gateway, only if you need to expose other static contents or api’s. If not, you can use a Route53 – a custom domain name – attached to your api gateway. And it’ll be fully enough
You can try creating VPC endpoints for your existing VPC according to aws docs.
Interface VPC endpoints allow communication with AWS services from your VPC without requiring access to the public internet. Traffic to the configured service will be routed through the endpoint directly to the service.
Another approach is to have NAT Gateway to your VPC which enables your lambda to be accessed through your public subnet. You may need to have route specified in route table. Also having Nat gateway would cost you little more compared to VPC endpoints.
I read your question a few times to make sure I understand what you are trying to do. The way you ask the question, the answer is no.
If you take out the CloudFront requirement, then of course it is possible and it works perfectly; you can easily access the lambda URL from anywhere, including the Internet. With the CloudFront requirement, it is still possible to achieve what you’re trying to do, but you have to do it in a different manner. The URL to be accessed is not the URL of the lambda function; you have to access the URL of the CloudFront distribution and when you do that it triggers your lambda function to run from the CloudFront distribution edge locations and this is the reason the usage of a lambda function is this case is called Lambda@Edge. Now, don’t let that confuse you; it’s just a regular lambda function that gets deployed to the CloudFront distribution edge locations. The main steps to implement what you’re looking for are:
For detailed instructions, follow the steps outline here. I am sure it will work.