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

AWS VPC中公有子网Lambda访问私有子网Lambda超时问题排查

问题:VPC内公有子网Lambda访问私有子网Lambda超时的网络配置缺失点

我创建了一个VPC,包含三个子网:A、B为私有子网,C为公有子网(已关联带有Internet Gateway的对应路由表)。部署在公有子网C的Lambda函数尝试访问部署在私有子网A、B的Lambda函数时,出现10秒超时。实验所用的CloudFormation模板如下:

AWSTemplateFormatVersion: "2010-09-09"

Parameters:
  ProductName:
    Type: String
    Default: 'vpc-test'
    Description: The name of the product
  EnvironmentCode:
    Type: String
    Default: 'test'
    AllowedValues:
      - test
      - stg
      - prod
      - sandbox
    Description: The environment code used in the naming of all AWS services.


Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: "10.0.0.0/16"
      EnableDnsHostnames: true
      EnableDnsSupport: true

  PrivateSubnetA:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Select
        - 0
        - !GetAZs
          Ref: 'AWS::Region' #select the 1st availability zone in the region
      VpcId: !Ref VPC
      CidrBlock: "10.0.0.0/24"

  PrivateSubnetB:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Select
        - 1
        - !GetAZs
          Ref: 'AWS::Region' #select the 2nd availability zone in the region
      VpcId: !Ref VPC
      CidrBlock: "10.0.1.0/24"

  PublicSubnetC:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Select
        - 1
        - !GetAZs
          Ref: 'AWS::Region' #select the 2nd availability zone in the region
      VpcId: !Ref VPC
      CidrBlock: "10.0.2.0/24"
      MapPublicIpOnLaunch: true

  RouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref "VPC"

  InternetGateway:
    Type: "AWS::EC2::InternetGateway"

  VPCGatewayAttachment:
    Type: "AWS::EC2::VPCGatewayAttachment"
    Properties:
      VpcId: !Ref "VPC"
      InternetGatewayId: !Ref "InternetGateway"

  InternetRoute:
    Type: "AWS::EC2::Route"
    Properties:
      DestinationCidrBlock: "0.0.0.0/0"
      GatewayId: !Ref InternetGateway
      RouteTableId: !Ref RouteTable

  PublicSubnetCRouteTableAssociation:
    Type: "AWS::EC2::SubnetRouteTableAssociation"
    Properties:
      RouteTableId: !Ref RouteTable
      SubnetId: !Ref PublicSubnetC

  PublicLambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      Architectures:
        - x86_64
      Code:
        ZipFile:
          Fn::Sub: |
            # Imports
            import io
            import boto3
            
            lambda_client = boto3.client('lambda')
            
            def handler(event, context):
                lambda_client.invoke(
                    FunctionName="lambda-${AWS::Region}-${EnvironmentCode}-${ProductName}-subnet-test",
                    InvocationType='RequestResponse',
                    Payload=b''
                )
                return "successfully accessed private lambda function!"

      Description: "function to test VPC s3 endpoint"
      FunctionName:
         Fn::Sub: "lambda-${AWS::Region}-${EnvironmentCode}-${ProductName}-s3-test"
      Handler: "index.handler"
      PackageType: Zip
      Role: !GetAtt LambdaIAMRole.Arn
      Runtime: python3.10
      Timeout: 10
      VpcConfig:
        SecurityGroupIds:
          - Fn::GetAtt: [VPC, DefaultSecurityGroup]
        SubnetIds:
          - Ref: PublicSubnetC

  PrivateLambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      Architectures:
        - x86_64
      Code:
        ZipFile: |
          def handler(event, context):
            return "successfully accessed private lambda function!"
      Description: "function to test private subnets within VPC"
      FunctionName:
        Fn::Sub: "lambda-${AWS::Region}-${EnvironmentCode}-${ProductName}-subnet-test"
      Handler: "index.handler"
      PackageType: Zip
      Role: !GetAtt LambdaIAMRole.Arn
      Runtime: python3.10
      Timeout: 10
      VpcConfig:
        SecurityGroupIds:
          - Fn::GetAtt: [ VPC, DefaultSecurityGroup ]
        SubnetIds:
          - Ref: PrivateSubnetA
          - Ref: PrivateSubnetB

  LambdaIAMRole:
    Type: 'AWS::IAM::Role'
    Properties:
      RoleName:
        Fn::Sub: "iam-${AWS::Region}-${EnvironmentCode}-lambda-role"
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      Policies:
        - PolicyName: 'root'
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - "logs:CreateLogGroup"
                  - "logs:CreateLogStream"
                  - "logs:PutLogEvents"
                Resource: arn:aws:logs:*:*:*
        - PolicyName: 'vpc'
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - "ec2:CreateNetworkInterface"
                  - "ec2:DescribeNetworkInterfaces"
                  - "ec2:DeleteNetworkInterface"
                Resource: "*"
        - PolicyName: 'lambda'
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - "lambda:*"
                Resource: "*"

我预期公有Lambda函数返回“successfully accessed private lambda function!”,但实际因VPC网络问题出现10秒超时。


解决方案:补充Lambda VPC接口端点配置

超时的核心原因是:部署在VPC内的Lambda调用Lambda API时,默认会尝试通过公网访问,但私有子网内的Lambda没有公网出口,且公有子网的Lambda通过公网调用Lambda API的路径无法确保私有子网Lambda能被正常触发。需要添加Lambda服务的VPC接口端点,让VPC内的Lambda通过内网访问Lambda服务,同时确保DNS解析正常。

具体需要在CloudFormation模板的Resources部分添加以下配置:

LambdaVPCEndpoint:
  Type: AWS::EC2::VPCEndpoint
  Properties:
    ServiceName: !Sub "com.amazonaws.${AWS::Region}.lambda"
    VpcId: !Ref VPC
    SecurityGroupIds:
      - !GetAtt VPC.DefaultSecurityGroup
    SubnetIds:
      - !Ref PrivateSubnetA
      - !Ref PrivateSubnetB
      - !Ref PublicSubnetC
    PrivateDnsEnabled: true

配置说明:

  • ServiceName:指定对应区域的Lambda服务端点,通过!Sub动态生成符合当前区域的端点名称。
  • SecurityGroupIds:关联VPC默认安全组,该安全组默认允许VPC内所有流量入站,确保Lambda和VPC端点之间的通信不受安全组限制。
  • SubnetIds:将端点部署到所有涉及的子网(私有A、B和公有C),保证所有子网内的Lambda都能通过内网访问Lambda服务。
  • PrivateDnsEnabled: true:启用私有DNS解析,这样boto3客户端会自动使用VPC内的私有域名访问Lambda服务,无需修改现有代码中的调用逻辑。

额外检查点:

  1. 私有子网A、B默认使用VPC的默认路由表,该路由表默认允许VPC内所有流量互通,无需额外配置路由规则。
  2. 确认Lambda的IAM角色已具备调用Lambda API的权限(当前模板中的lambda策略已包含lambda:*权限,满足需求)。

添加上述配置后,重新部署CloudFormation栈,公有子网的Lambda即可通过内网正常调用私有子网内的Lambda函数,不会再出现超时问题。


内容的提问来源于stack exchange,提问作者Job Heersink

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 07:19:57