I’m new to AWS and struggling to understand how they’ve laid out their components, especially around networking & access.
In this case, I’m toying with an API GW and a "hello world" lambda. I made the lambda (no VPC) and hooked it up to an API GW, and now I have a publicly-accessible lambda. I didn’t understand why the lambda was callable without being in a VPC, but I finally stumbled upon this explanation in the docs: https://docs.aws.amazon.com/lambda/latest/dg/configuration-vpc.html#vpc-internet
Seems weird to default open, but okay.
So, now I’m trying to close off the API via the networking-related config. So I created a VPC & private subnets (no IGW, NOT publicly accessible), and put the lambda in there. I felt confident it would no longer be accessible, ‘cuz that’s how VPC & networking works, yet the lambda is still publicly accessible! Why?
The API GW doesn’t have access to this VPC, and in any case, this VPC doesn’t have internet access. The way these components are interacting doesn’t seem to make sense. What’s going on here?
3
Answers
My mistake was thinking lambdas can be put in a VPC. Rather, they can only be given access to a VPC:
https://docs.aws.amazon.com/lambda/latest/dg/configuration-vpc.html
So all my comments about VPC logic don't apply, and that's why my lambda is publicly accessible.
Furthermore, in case this is helpful to others:
I originally had the misconception that all AWS components were basically servers, and they all needed to be put in VPCs. This pattern does not apply to serverless components! (including S3, lambda, dynamoDB, etc) These operate in their own area, and the point of the component is to (mostly) abstract away things like networking details. Instead, they tend to control access via other methods, like IAM policies, security groups, "integrations", etc
Check for Internet Gateway, Nat gateway. Check for the actual VPC the LAMDA is connected to, sometimes having multiple can be confusing and lastly also check the VPC End point
API Gateway allows you to create private endpoints as well as public ones. It sounds like you want a private endpoint.