Lambda in a VPC: reaching the internet and AWS services

Attaching a Lambda function to a VPC gives it private network access and takes away its internet access. What each side needs — execution role ENI permissions, private subnets with a NAT gateway or VPC endpoints, security groups — with a known-good setup and known-bad ones with their symptoms (usually a timeout with no error).

markdownpatternv4WR7Y-0CMKstage: buildtrust: officialservice: lambdaservice: vpcinterface: cliinterface: iacLambda VPCLambda internet accessLambda NAT gatewayLambda public subnetAWSLambdaVPCAccessExecutionRoleLambda VPC endpointLambda timeout VPCENILimitReachedExceptionSubnetIPAddressLimitReachedExceptionEC2AccessDeniedExceptionvpc-config

Created 18 Oct 2026 · Modified 23 Oct 2026 · 4 versions

Lambda in a VPC

Only attach a function to a VPC if it must reach private resources, such as a database, an internal service or a private endpoint. Once it is attached, the function has no internet access and no public IP, even in a public subnet. Every call to an AWS API or the internet needs a NAT gateway or a VPC endpoint. Without one, the call hangs until Task timed out.

What crosses the handoff

SideProvides / expects
LambdaCreates network interfaces in the subnets you list, using the execution role. That needs the ec2:CreateNetworkInterface/Describe…/Delete… permissions in AWSLambdaVPCAccessExecutionRole. The role grants the right to create interfaces, not any network path.
VPCSubnets with free IP addresses, security groups that allow the function's outbound traffic, and routes: private subnets → NAT gateway (a zonal one in a public subnet, or a regional one that needs no public subnet) → internet gateway, and/or VPC endpoints for the AWS services the function calls.

Known-good

  1. Two or more private subnets in different Availability Zones, each with a route 0.0.0.0/0 → nat-…. A zonal NAT gateway sits in a public subnet whose route goes to the internet gateway; a regional NAT gateway (create-nat-gateway --vpc-id … --availability-mode regional) needs no public subnet and serves every AZ with one ID (reference/vpc/routing-and-gateways.md).
  2. A security group for the function with outbound HTTPS, plus whatever the database needs. Allow inbound on the database's group from the function's group.
  3. The execution role has AWSLambdaVPCAccessExecutionRole (or equivalent) and the function's own permissions.
  4. Attach:
aws lambda update-function-configuration --function-name <fn> \
  --vpc-config SubnetIds=<subnet-a>,<subnet-b>,SecurityGroupIds=<sg>
aws lambda wait function-updated-v2 --function-name <fn>
  1. Optional, to avoid NAT for AWS traffic: VPC endpoints (gateway endpoints for S3 and DynamoDB; interface endpoints for others such as secretsmanager, sqs, sts) with private DNS on. Their security groups must allow 443 from the function's group. Endpoint policies are a second policy layer (patterns/iam-to-vpc-endpoints.md).

Known-bad

ConfigurationSymptom
Function in a public subnet, expecting internetTask timed out after N seconds on the first outbound call: Lambda never gets a public IP
Private subnets with no NAT route and no endpoint for the serviceSame timeout. No error from the SDK unless its own timeout is shorter
Gateway endpoint for S3 created but not associated with the function's route tablesS3 calls time out; other calls work
Interface endpoint without private DNSThe SDK resolves the public name and times out
Execution role without the ENI permissionsUpdate or invoke fails with EC2AccessDeniedException (502); the function's state shows the reason
Subnets nearly fullSubnetIPAddressLimitReachedException (502) on invoke or scale-out
Many functions or subnets × security group combinationsENILimitReachedException (502): the per-VPC Lambda network-interface quota is reached
A subnet or security group deleted after configurationInvalidSubnetIDException / InvalidSecurityGroupIDException (502)
Security group allows no outbound trafficTimeouts on every connection

Which side is wrong?

  • Timeout with no error → the network side: routes, NAT, endpoints, security group egress. Reachability Analyzer from the function's network interface names the blocking layer (guides/vpc/diagnose-connection-timeout.md). Check what the function calls, then aws ec2 describe-route-tables --filters Name=association.subnet-id,Values=<subnet>.
  • A 502 exception naming EC2, ENI or subnets → the Lambda side's set-up: the execution role, subnet IP capacity or quotas (reference/lambda/errors.md).
  • The connection is refused by the database → the database's security group does not allow the function's group.

Design notes

  • Make SDK client timeouts shorter than the function timeout, so a missing route produces an error message rather than a bare Task timed out.
  • Updating VPC settings puts the function into a Pending update. Wait before invoking (ResourceConflictException otherwise).
  • To detach, use --vpc-config SubnetIds=[],SecurityGroupIds=[].

Read this document as markdown — the same bytes an agent receives.