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服务,无需修改现有代码中的调用逻辑。
额外检查点:
- 私有子网A、B默认使用VPC的默认路由表,该路由表默认允许VPC内所有流量互通,无需额外配置路由规则。
- 确认Lambda的IAM角色已具备调用Lambda API的权限(当前模板中的
lambda策略已包含lambda:*权限,满足需求)。
添加上述配置后,重新部署CloudFormation栈,公有子网的Lambda即可通过内网正常调用私有子网内的Lambda函数,不会再出现超时问题。
内容的提问来源于stack exchange,提问作者Job Heersink
相关产品推荐
相关产品推荐

