对预签名 S3 URL 的 Lambda HTTP 请求超时
Lambda HTTP request to presigned S3 URL timing out
我有一个自定义 Lambda 资源,它初始化我的数据库,然后应该在完成后调用预签名的 S3 url。它正在正确启动数据库,但在调用 S3 时超时。我的猜测是我在我的 CloudFormation 模板中做错了什么,这是由于我有限的网络知识导致的。将不胜感激任何帮助。提前致谢!
精简 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
您正在将 lambda 放在 PublicSubnet1
中。因此,尽管有 NAT 或 Internet 网关,您的 lambda 将无法连接到 Internet。您需要将您的函数放在 私有子网 中,并配置您的私有子网以使用 NAT 网关。来自 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.
或者,使用 S3 VPC gateway endpoint 并将其与 public 子网的路由表相关联。这样您的函数将使用网关而不是互联网访问 s3。 在这种情况下不需要 NAT 或私有子网。
我有一个自定义 Lambda 资源,它初始化我的数据库,然后应该在完成后调用预签名的 S3 url。它正在正确启动数据库,但在调用 S3 时超时。我的猜测是我在我的 CloudFormation 模板中做错了什么,这是由于我有限的网络知识导致的。将不胜感激任何帮助。提前致谢!
精简 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
您正在将 lambda 放在 PublicSubnet1
中。因此,尽管有 NAT 或 Internet 网关,您的 lambda 将无法连接到 Internet。您需要将您的函数放在 私有子网 中,并配置您的私有子网以使用 NAT 网关。来自 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.
或者,使用 S3 VPC gateway endpoint 并将其与 public 子网的路由表相关联。这样您的函数将使用网关而不是互联网访问 s3。 在这种情况下不需要 NAT 或私有子网。