4

I am experimenting with AWS Lambda, with a small piece of code that would fetch some files from S3. Unfortunately I cannot even access internet resources when I put my Lambda function into a VPC, although I believe the VPC is configured properly.

I have the following code sample, that demonstrates what I am trying to do: the urlopen call simply keeps timing out due to the networking issue (and works just fine if I set my Lambda to be outside of VPCs).

import json

def lambda_handler(event, context):
    # TODO implement

    import urllib.request
    contents = urllib.request.urlopen("https://api.ipify.org?format=json").read()


    return {
        "statusCode": 200,
        "body": json.dumps( str(contents) )
    }

I have collected my VPC etc configuration, can someone maybe spot any issue around it? I believe I have avoided the basic issues, so not being able to access internet resources leaves me absolutely puzzled.

VPC:
    Name: S3 CONNECTION TEST
    VPC ID: vpc-09025133f1b68a1cc
    State: available
    IPv4 CIDR: 10.0.0.0/24

Subnet:
    Name: S3-connection-check-subnet
    Subnet ID: subnet-0e2904283f7b644e3
    State: available
    VPC: vpc-09025133f1b68a1cc | S3 CONNECTION TEST
    Routing Table: rtb-0e0d8951583d0c5ca | S3 CONNECTIVITY check

Internet Gateway:
    Name: S3 connection test
    ID: igw-07aabbe0d979d0ca3
    State: attached
    VPC: vpc-09025133f1b68a1cc | S3 CONNECTION TEST 

NAT Gateway:
    Name: S3 connection test NAT
    ID: nat-06d25cfd034108851
    Status: available
    Status Message: -
    Elastic IP Address: (some valid public IP address)
    Private IP address: 10.0.0.203
    Network interface: eni-0fefa7310a1bcf050
    VPC: vpc-09025133f1b68a1cc | S3 CONNECTION TEST
    Subnet: subnet-0e2904283f7b644e3 | S3-connection-check-subnet

Routing Table:
    Name: S3 CONNECTIVITY check
    Route Table ID: rtb-0e0d8951583d0c5ca
    Explicit association: 1 Subnet
    Main: Yes
    VPC: vpc-09025133f1b68a1cc | S3 CONNECTION TEST

    Routes:
        Route 1:
            Destination: 10.0.0.0/24
            Target: local
            Status: Active
            Propagated: No
        Route 2:
            Destination: 0.0.0.0/0
            Target: nat-06d25cfd034108851
            Status: Active
            Propagated: No

Lambda function:
    Name: Test-S3-Read
    VPC: vpc-09025133f1b68a1cc
    Subnets: subnet-0e2904283f7b644e3 (10.0.0.0/24) | xx-xxxx-xx S3-connection-check-subnet
    Security Groups: sg-0e5ee380770e6e4cd (Allow All) | Allow All

Security Groups:
    Name: sg-0e5ee380770e6e4cd (Allow All) | Allow All
    Inbound rules: 
        Rule 1:
            Type: ALL Traffic
            Protocol: ALL
            Port Range: All
            Source: 0.0.0.0/0
    Outbound rules: 
        Rule 1:
            Type: ALL Traffic
            Protocol: ALL
            Port Range: ALL
            Destination: 0.0.0.0/0      
Tim
  • 31,888
  • 7
  • 52
  • 78
  • It's not possible for a NAT Gateway to serve other devices on the same subnet the NAT Gateway it is placed on, because the route table for the subnet where the gateway is placed must send 0.0.0.0 to the VPC's IGW. You have the NAT Gateway trying to use itself as its own default route. – Michael - sqlbot Oct 10 '18 at 12:14
  • OK, that was it: incorrect routing settings. Thanks @Michael-sqlbot for pointing that out: this is not absolutely intuitive, but works indeed like that. – Peter G. Horvath Oct 10 '18 at 13:55
  • @Michael - sqlbot I you added your answer as answer, I would be able to accept it as the official answer so that you get the points. :) – Peter G. Horvath Oct 17 '18 at 15:25
  • I appreciate that, but I just dropped a couple of hints, which you took and ran with, solved your own problem, and posted a solid answer that's useful to future visitors. Feel free to accept your own answer. – Michael - sqlbot Oct 17 '18 at 19:07

1 Answers1

3

Based on Michael's answer, I was able to figure this out finally. (Many-many thanks to him! :))

Since I have struggled with this so much, I am capturing the final solution, just in case someone hits the same issue.

I ended up using three Subnets, an Internet Gateway, a NAT Gateway and two distinct Routing tables (in addition to the main routing table of the VPC):

  • One small subnet that hosts the NAT Gateway only with a dedicated routing table

    • Its routing table contains two entries:
      • the VPC specific traffic (in my case 10.0.0.0/24) is routed to to local
      • other traffic (0.0.0.0/0) is routed to the to Internet Gateway
  • Two subnets that host the Lambda services with another routing table

    • That routing table contains two entries:
      • the VPC specific traffic (in my case 10.0.0.0/24) is routed to to local
      • other traffic (0.0.0.0/0) is routed to the to NAT Gateway

Actually, AWS documentation has a pretty good explanation on this, looking at diagram of the their sample setup helped me a lot.