You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VPC内AWS Lambda访问外部API配置问题求助(Serverless框架)

Lambda VPC 出站互联网访问配置修复方案

核心问题分析

你的配置存在三个关键错误,导致Lambda无法访问外部API:

  1. 多个NAT网关共享同一个弹性IP(EIP):AWS不允许多个NAT网关绑定同一个EIP,会导致NAT网关无法正常工作。
  2. Lambda部署在公共子网且路由指向互联网网关(IGW):VPC内的Lambda即使在公共子网,默认也不会被分配公网IP,无法直接通过IGW访问互联网,必须通过NAT网关转发流量。
  3. 缺少私有子网及对应路由配置:Lambda需要部署到私有子网,私有子网的路由表需配置默认路由指向NAT网关。

具体修复步骤

1. 为每个NAT网关分配独立EIP

修改routing.yml,为两个NAT网关分别创建EIP,并添加私有子网路由表:

Resources:
  # 公共路由表(仅用于NAT网关所在的公共子网)
  RouteTablePublic:
    DependsOn: VPCGA
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: 'Name'
          Value: 'RouteTablePublic'

  RoutePublic:
    Type: AWS::EC2::Route
    Properties:
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway
      RouteTableId: !Ref RouteTablePublic

  # NAT网关A的独立EIP
  NatGatewayEIPA:
    Type: AWS::EC2::EIP
    Properties:
      Domain: vpc

  NatGatewayA:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt NatGatewayEIPA.AllocationId
      SubnetId: !Ref SubnetA

  # NAT网关B的独立EIP
  NatGatewayEIPB:
    Type: AWS::EC2::EIP
    Properties:
      Domain: vpc

  NatGatewayB:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt NatGatewayEIPB.AllocationId
      SubnetId: !Ref SubnetB

  # 公共子网关联公共路由表
  RouteTableAssociationSubnetA:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref RouteTablePublic
      SubnetId: !Ref SubnetA

  RouteTableAssociationSubnetB:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref RouteTablePublic
      SubnetId: !Ref SubnetB

  # 私有子网路由表A(指向NAT网关A)
  RouteTablePrivateA:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: 'Name'
          Value: 'RouteTablePrivateA'

  RoutePrivateA:
    Type: AWS::EC2::Route
    Properties:
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId: !Ref NatGatewayA
      RouteTableId: !Ref RouteTablePrivateA

  # 私有子网路由表B(指向NAT网关B)
  RouteTablePrivateB:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: 'Name'
          Value: 'RouteTablePrivateB'

  RoutePrivateB:
    Type: AWS::EC2::Route
    Properties:
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId: !Ref NatGatewayB
      RouteTableId: !Ref RouteTablePrivateB

2. 创建私有子网供Lambda部署

修改vpc.yml,添加两个私有子网(关闭公网IP自动分配)并关联到私有路由表:

Resources:
  # 保留原有VPC、公共子网、安全组等配置...

  # 私有子网A
  SubnetPrivateA:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: ${self:provider.region}a
      CidrBlock: ${self:custom.VPC_CIDR}.1.0.0/24
      MapPublicIpOnLaunch: false
      Tags:
        - Key: 'Name'
          Value: 'SubnetPrivateA'

  # 私有子网B
  SubnetPrivateB:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: ${self:provider.region}b
      CidrBlock: ${self:custom.VPC_CIDR}.1.1.0/24
      MapPublicIpOnLaunch: false
      Tags:
        - Key: 'Name'
          Value: 'SubnetPrivateB'

  # 私有子网关联对应路由表
  RouteTableAssociationSubnetPrivateA:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref RouteTablePrivateA
      SubnetId: !Ref SubnetPrivateA

  RouteTableAssociationSubnetPrivateB:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref RouteTablePrivateB
      SubnetId: !Ref SubnetPrivateB

3. 修改Lambda配置,部署到私有子网

更新serverless.yml中的函数子网配置,切换为私有子网:

functions:
  refresh-api:
    name: update-order-status-${opt:stage, 'dev'}
    handler: update-order-status/main.handler
    timeout: 30
    vpc:
      securityGroupIds:
        - !Ref LambdaSecurityGroup
      subnetIds:
        - !Ref SubnetPrivateA
        - !Ref SubnetPrivateB
    events:
      - httpApi:
          method: ANY
          path: /{proxy+}

  order-receiver:
    name: order-receiver-${opt:stage, 'dev'}
    handler: order-receiver/main.handler
    timeout: 120
    vpc:
      securityGroupIds:
        - !Ref LambdaSecurityGroup
      subnetIds:
        - !Ref SubnetPrivateA
        - !Ref SubnetPrivateB
    events:
      - sqs:
          arn: !GetAtt ReceiveOrderQueue.Arn
          batchSize: 10

4. 确认Lambda安全组出站规则

确保Lambda安全组允许HTTPS/HTTP出站流量(默认已开放,若被修改需手动添加):

LambdaSecurityGroup:
  Type: AWS::EC2::SecurityGroup
  Properties:
    VpcId: !Ref VPC
    GroupDescription: 'Security group for Lambdas'
    SecurityGroupEgress:
      - IpProtocol: tcp
        FromPort: 80
        ToPort: 80
        CidrIp: 0.0.0.0/0
      - IpProtocol: tcp
        FromPort: 443
        ToPort: 443
        CidrIp: 0.0.0.0/0
    Tags:
      - Key: 'RefreshLambdaSecurityGroup'
        Value: 'LambdaSecurityGroup'

验证步骤

部署修改后的配置后,可通过以下方式验证:

  • 在Lambda中添加测试代码调用外部API(如https://httpbin.org/get)并打印结果
  • 查看Lambda执行日志,确认是否成功获取响应
  • 检查NAT网关监控指标(如BytesOutToDestination),确认有流量通过

内容的提问来源于stack exchange,提问作者Carlos Mendez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 10:43:09