1

I have a Custom Lambda resource that inits my DB and then is supposed make the call to the presigned S3 url when done. It's initing the DB correctly but is timing out when making the call to S3. My guess is I did something wrong in my CloudFormation template that's causing that due to my limited networking knowledge. Would appreciate any help. Thank you in advance!

Trimmed down YAML:

AWSTemplateFormatVersion: 2010-09-09
Transform: "AWS::Serverless-2016-10-31"
Resources:
  InternetGateway:
    Type: "AWS::EC2::InternetGateway"
    Properties:
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-InternetGateway
  VPC:
    Type: "AWS::EC2::VPC"
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: "true"
      EnableDnsHostnames: "true"
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-VPC
  VPCGatewayAttachment:
    Type: "AWS::EC2::VPCGatewayAttachment"
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway
  NATGateway:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt ElasticIPAddress.AllocationId
      SubnetId: !Ref PublicSubnet1
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-NATGateway
  ElasticIPAddress:
    Type: AWS::EC2::EIP
    Properties:
      Domain: VPC
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-EIP
  PublicRouteTable:
    Type: "AWS::EC2::RouteTable"
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: Public
  PublicRoute1:
    Type: "AWS::EC2::Route"
    Properties:
      RouteTableId: !Ref PublicRouteTable
      GatewayId: !Ref InternetGateway
      DestinationCidrBlock: 0.0.0.0/0
    DependsOn:
      - InternetGateway
  PublicSubnet1:
    Type: "AWS::EC2::Subnet"
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.0.0/24
      AvailabilityZone: !Select [0, !GetAZs ]
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-PublicSubnet1
  CreateRDSDatabaseLambdaSG:
    Type: "AWS::EC2::SecurityGroup"
    Properties:
      VpcId: !Ref VPC
      GroupDescription: Allow Lambda to access RDS in same VPC
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-CreateRDSDatabaseLambdaSG
  LambdaRDSCFNInit:
    Type: AWS::Serverless::Function
    DependsOn:
      - InternetGateway
      - VPC
      - VPCGatewayAttachment
      - NATGateway
      - ElasticIPAddress
      - PublicRouteTable
      - PublicRoute1
      - PublicSubnet1
      - CreateRDSDatabaseLambdaSG
    Properties:
      CodeUri: CreateRDSDatabase/
      Description: "Lambda function which will execute when this CFN template is created, updated or deleted"
      Handler: app.createRDSDatabase
      Runtime: nodejs12.x
      Timeout: 300
      VpcConfig:
        SecurityGroupIds:
          - !Ref CreateRDSDatabaseLambdaSG
        SubnetIds:
          - !Ref PublicSubnet1
      Environment:
        Variables:
          RDS_ENDPOINT: !GetAtt RDSCluster.Endpoint.Address
          RDS_DB_NAME: !Ref RDSDBName
          RDS_USERNAME: !Ref RDSUserName
          RDS_PASSWORD: !Ref RDSPassword

  LambdaRDSCFNTrigger:
    Type: Custom::ProvisionRDS
    DependsOn: LambdaRDSCFNInit
    Version: 1.0
    Properties:
      ServiceToken: !GetAtt LambdaRDSCFNInit.Arn
4

1 回答 1

3

You are placing your lambda in PublicSubnet1. Thus, your lambda will not have internet connectivity despite your NAT or Internet gateway. You need to place your function in a private subnet, and configure your private subnet to use the NAT gateway. From docs:

To access private resources, connect your function to private subnets. If your function needs internet access, use network address translation (NAT). Connecting a function to a public subnet doesn't give it internet access or a public IP address.

Alternatively, use S3 VPC gateway endpoint and associate it with route tables of your public subnet. This way your function will access s3 using the gateway, rather then internet. No need for NAT nor private subnet in this case.

于 2020-11-15T03:10:00.360 回答