【问题标题】:Lambda Function in VPC has no Internet AccessVPC 中的 Lambda 函数无法访问 Internet
【发布时间】:2017-11-17 22:24:47
【问题描述】:

我的 Lambda 函数可以访问 VPC 中的其他资源,但是一旦它尝试向 Internet 发出请求,它就会超时。我有以下内容:

  • 两个私有子网
  • 将 0.0.0.0/0 路由到 Internet 网关的路由表。
  • 一对 ACL 规则和一个 Lambda 安全组

任何帮助都会有所帮助。这是我的 CF 模板:

AWSTemplateFormatVersion: 2010-09-09
Description: VPC Stack
Resources:
  VPC:
    Type: 'AWS::EC2::VPC'
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsHostnames: true
      Tags:
        - Key: Application
          Value: !Ref 'AWS::StackId'
  Subnet1:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.3.0/24
      AvailabilityZone: 'us-east-1b'
      Tags:
        - Key: Application
          Value: !Ref 'AWS::StackId'
  Subnet2:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.4.0/24
      AvailabilityZone: 'us-east-1e'
      Tags:
        - Key: Application
          Value: !Ref 'AWS::StackId'
  InternetGateway:
    Type: 'AWS::EC2::InternetGateway'
    Properties:
      Tags:
        - Key: Application
          Value: !Ref 'AWS::StackId'
  AttachGateway:
    Type: 'AWS::EC2::VPCGatewayAttachment'
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway
  RouteTable:
    Type: 'AWS::EC2::RouteTable'
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Application
          Value: !Ref 'AWS::StackId'
  Route:
    Type: 'AWS::EC2::Route'
    DependsOn: AttachGateway
    Properties:
      RouteTableId: !Ref RouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway
  SubnetRouteTableAssociation1:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId: !Ref Subnet1
      RouteTableId: !Ref RouteTable
  SubnetRouteTableAssociation2:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId: !Ref Subnet2
      RouteTableId: !Ref RouteTable
  NetworkAcl:
    Type: 'AWS::EC2::NetworkAcl'
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Application
          Value: !Ref 'AWS::StackId'
  InboundHTTPNetworkAclEntry:
    Type: 'AWS::EC2::NetworkAclEntry'
    Properties:
      NetworkAclId: !Ref NetworkAcl
      RuleNumber: '100'
      Protocol: '6'
      RuleAction: allowAWSTemplateFormatVersion: 2010-09-09
Description: VPC Stack
Resources:
  VPC:
    Type: 'AWS::EC2::VPC'
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsHostnames: true
      Tags:
        - Key: Application
          Value: !Ref 'AWS::StackId'
  Subnet1:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.3.0/24
      AvailabilityZone: 'us-east-1b'
      Tags:
        - Key: Application
          Value: !Ref 'AWS::StackId'
  Subnet2:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.4.0/24
      AvailabilityZone: 'us-east-1e'
      Tags:
        - Key: Application
          Value: !Ref 'AWS::StackId'
  InternetGateway:
    Type: 'AWS::EC2::InternetGateway'
    Properties:
      Tags:
        - Key: Application
          Value: !Ref 'AWS::StackId'
  AttachGateway:
    Type: 'AWS::EC2::VPCGatewayAttachment'
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway
  RouteTable:
    Type: 'AWS::EC2::RouteTable'
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Application
          Value: !Ref 'AWS::StackId'
  Route:
    Type: 'AWS::EC2::Route'
    DependsOn: AttachGateway
    Properties:
      RouteTableId: !Ref RouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway
  SubnetRouteTableAssociation1:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId: !Ref Subnet1
      RouteTableId: !Ref RouteTable
  SubnetRouteTableAssociation2:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId: !Ref Subnet2
      RouteTableId: !Ref RouteTable
  NetworkAcl:
    Type: 'AWS::EC2::NetworkAcl'
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Application
          Value: !Ref 'AWS::StackId'
  InboundHTTPNetworkAclEntry:
    Type: 'AWS::EC2::NetworkAclEntry'
    Properties:
      NetworkAclId: !Ref NetworkAcl
      RuleNumber: '100'
      Protocol: '6'
      RuleAction: allow
      Egress: 'false'
      CidrBlock: 0.0.0.0/0
      PortRange:
        From: '80'
        To: '80'
  InboundSSHNetworkAclEntry:
    Type: 'AWS::EC2::NetworkAclEntry'
    Properties:
      NetworkAclId: !Ref NetworkAcl
      RuleNumber: '101'
      Protocol: '6'
      RuleAction: allow
      Egress: 'false'
      CidrBlock: 0.0.0.0/0
      PortRange:
        From: '22'
        To: '22'
  InboundResponsePortsNetworkAclEntry:
    Type: 'AWS::EC2::NetworkAclEntry'
    Properties:
      NetworkAclId: !Ref NetworkAcl
      RuleNumber: '102'
      Protocol: '6'
      RuleAction: allow
      Egress: 'false'
      CidrBlock: 0.0.0.0/0
      PortRange:
        From: '1024'
        To: '65535'
  OutBoundNetworkAclEntry:
    Type: 'AWS::EC2::NetworkAclEntry'
    Properties:
      NetworkAclId: !Ref NetworkAcl
      RuleNumber: '103'
      Protocol: '6'
      RuleAction: allow
      Egress: 'true'
      CidrBlock: 0.0.0.0/0
      PortRange:
        From: '0'
        To: '65535'
  SubnetNetworkAclAssociation1:
    Type: 'AWS::EC2::SubnetNetworkAclAssociation'
    Properties:
      SubnetId: !Ref Subnet1
      NetworkAclId: !Ref NetworkAcl
  SubnetNetworkAclAssociation2:
    Type: 'AWS::EC2::SubnetNetworkAclAssociation'
    Properties:
      SubnetId: !Ref Subnet2
      NetworkAclId: !Ref NetworkAcl
  LambdaSecurityGroup:
      Type: AWS::EC2::SecurityGroup
      Properties: 
          VpcId: !Ref VPC
          GroupDescription: Access to Lambda functions
          SecurityGroupIngress:
            - CidrIp: 0.0.0.0/0
              IpProtocol: -1
         SecurityGroupEgress:
            - CidrIp: 0.0.0.0/0
              IpProtocol: -1
Outputs:
  VpcId:
    Description: VPC ID
    Value: !Ref VPC
    Export:
      Name: !Sub "Portal-VpcId"
  Subnet1:
    Description: Subnet ID 1
    Value: !Ref Subnet1
    Export:
      Name: !Sub "Portal-SubnetID1"
  Subnet2:
    Description: Subnet ID 2
    Value: !Ref Subnet2
    Export:
      Name: !Sub "Portal-SubnetID2"      
  LambdaSecurityGroup:
    Description: Access to Lambda functions
    Value: !Ref LambdaSecurityGroup
    Export:
      Name: !Sub "LambdaSecurityGroup"      
      Egress: 'false'
      CidrBlock: 0.0.0.0/0
      PortRange:
        From: '80'
        To: '80'
  InboundResponsePortsNetworkAclEntry:
    Type: 'AWS::EC2::NetworkAclEntry'
    Properties:
      NetworkAclId: !Ref NetworkAcl
      RuleNumber: '102'
      Protocol: '6'
      RuleAction: allow
      Egress: 'false'
      CidrBlock: 0.0.0.0/0
      PortRange:
        From: '1024'
        To: '65535'
  OutBoundNetworkAclEntry:
    Type: 'AWS::EC2::NetworkAclEntry'
    Properties:
      NetworkAclId: !Ref NetworkAcl
      RuleNumber: '103'
      Protocol: '6'
      RuleAction: allow
      Egress: 'true'
      CidrBlock: 0.0.0.0/0
      PortRange:
        From: '0'
        To: '65535'
  SubnetNetworkAclAssociation1:
    Type: 'AWS::EC2::SubnetNetworkAclAssociation'
    Properties:
      SubnetId: !Ref Subnet1
      NetworkAclId: !Ref NetworkAcl
  SubnetNetworkAclAssociation2:
    Type: 'AWS::EC2::SubnetNetworkAclAssociation'
    Properties:
      SubnetId: !Ref Subnet2
      NetworkAclId: !Ref NetworkAcl
  LambdaSecurityGroup:
      Type: AWS::EC2::SecurityGroup
      Properties: 
          VpcId: !Ref VPC
          GroupDescription: Access to Lambda functions
          SecurityGroupIngress:
            - CidrIp: 0.0.0.0/0
              IpProtocol: -1
          SecurityGroupEgress:
            - CidrIp: 0.0.0.0/0
              IpProtocol: -1
Outputs:
  VpcId:
    Description: VPC ID
    Value: !Ref VPC
    Export:
      Name: !Sub "Portal-VpcId"
  Subnet1:
    Description: Subnet ID 1
    Value: !Ref Subnet1
    Export:
      Name: !Sub "Portal-SubnetID1"
  Subnet2:
    Description: Subnet ID 2
    Value: !Ref Subnet2
    Export:
      Name: !Sub "Portal-SubnetID2"      
  LambdaSecurityGroup:
    Description: Access to Lambda functions
    Value: !Ref LambdaSecurityGroup
    Export:
      Name: !Sub "LambdaSecurityGroup"      

CF 模板 2:

Lambda:
    Type: "AWS::Lambda::Function"
    Properties:
      Handler: "index.handler"
      Environment: 
        Variables:
          Environment: !Ref Environment
      Role: !GetAtt LambdaExecutionRole.Arn
      Runtime: "nodejs6.10"
      VpcConfig:
        SecurityGroupIds:
          - !ImportValue "LambdaSecurityGroup"
        SubnetIds:
          - !ImportValue "Portal-SubnetID1"
          - !ImportValue "Portal-SubnetID2"
      Code: 
        S3Bucket: !Ref BaseS3Bucket
        S3Key:  
          !Join
            - ''
            - - !Ref TemplatePath
              - '/'
              - !Ref Environment
              - '/Quick-Links/build-output.zip'

【问题讨论】:

标签: amazon-web-services lambda amazon-cloudformation


【解决方案1】:

当您在 VPC 中执行 Lambda 函数时,Lambda 函数将只接收一个私有 IP 地址。它不会收到公共 IP 地址。

为了让任何 AWS 服务器通过互联网网关访问公共互联网,它必须:

  1. 有一个公共 IP 地址,并且
  2. 位于公共子网中(即直接访问 Internet 网关的子网)

由于您的 Lambda 函数没有该公共 IP 地址,因此即使它位于公共子网中,它也无法访问互联网。

要解决此问题,您必须在私有子网中执行 Lambda 函数。这是一个子网:

  1. 无法直接访问 Internet 网关,并且
  2. 通过 NAT 实例或 NAT 网关引导所有外向连接

【讨论】:

    【解决方案2】:

    如果您希望 Lambda 与互联网通信,您需要通过 NAT 实例进行路由。

    向您现有的 VPC 子网添加另外两个子网和一个 NAT 网关。然后,在新子网中设置路由表以通过 NAT 路由互联网。

    【讨论】:

    • @DominickPiganell - 澄清为什么 Chris 说您需要另外两个子网:当子网路由到 Internet 网关时,它是一个 public 子网.私有子网不通过 IGW 路由,但可以通过 NAT 网关(与 NAT 实例不同)进行路由。
    猜你喜欢
    • 2018-10-20
    • 2018-12-25
    • 2019-10-28
    • 2019-12-31
    • 2016-05-27
    • 2018-11-04
    • 2019-09-18
    • 2022-12-05
    相关资源
    最近更新 更多