我正在尝试在 VPC 的私有子网中创建 2 个 lambda 函数,lambda 将从 API 网关调用。
api 网关将有几条通往 lambda 的路径。
我创建了 2 个 VPC 端点,一个用于 lambda 调用 Secrets Manager,其中存储了对 RDS Aurora 的用户和密码访问权限,另一个用于 api 网关的 VPC 端点,因此它可以调用 lambda 函数。
我面临的问题是我收到错误消息:
{ "message": "Internal server error" }
尝试请求我的 API 网关时。
我的 lambda 函数似乎甚至没有被请求,当我在 AWS 控制台中使用测试按钮手动请求它时,它工作并生成日志,但是在我的机器上使用邮递员从 API 网关调用,只返回错误,lambda 函数不生成日志,网关日志也没有告诉我太多信息。来自网关的日志示例:
{
"requestId": "id",
"ip": "ipv4",
"caller": "-",
"user": "-",
"requestTime": "31/Mar/2023:15:47:35 +0000",
"httpMethod": "GET",
"resourcePath": "/{database_name}/{table_name}",
"status": "500",
"protocol": "HTTP/1.1",
"responseLength": "36"
}
这是我当前使用 SAM CLI 部署所有服务的 main.yaml 文件:
Resources:
DcpBackendReaderRole:
Type: AWS::IAM::Role
Properties:
RoleName: DcpBackendReaderRole
Tags:
- Key: "env"
Value: "3"
- Key: "serviceGroup"
Value: "2"
- Key: "owner"
Value: "1"
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole
- arn:aws:iam::aws:policy/service-role/AWSLambdaRole
Policies:
- PolicyName: SecretsManagerReadAccess
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- secretsmanager:GetSecretValue
Resource: !Sub 'arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:secrets/manager/key/for/user/and/pss-*'
- PolicyName: KMSDecryptAccess
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- kms:Decrypt
Resource: !Sub 'arn:aws:kms:${AWS::Region}:${AWS::AccountId}:key/key-id'
DcpBackendWriterRole:
Type: AWS::IAM::Role
Properties:
RoleName: DcpBackendWriterRole
Tags:
- Key: "env"
Value: "3"
- Key: "serviceGroup"
Value: "2"
- Key: "owner"
Value: "1"
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole
- arn:aws:iam::aws:policy/service-role/AWSLambdaRole
Policies:
- PolicyName: SecretsManagerReadAccess
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- secretsmanager:GetSecretValue
Resource: !Sub 'arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:secrets/manager/key/for/user/and/pss-*'
- PolicyName: KMSDecryptAccess
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- kms:Decrypt
Resource: !Sub 'arn:aws:kms:${AWS::Region}:${AWS::AccountId}:key/key-id'
DcpDbManagementLayer:
Type: AWS::Serverless::LayerVersion
Properties:
LayerName: DCP-Database-Management
Description: DCP Database Management Layer
ContentUri: layers/dcp-db-management/
CompatibleRuntimes:
- python3.9
RetentionPolicy: Retain
DcpApiGatewayLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub '/aws/apigateway/${DcpServerlessApiGtw}'
RetentionInDays: 14
DcpBackendReaderFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: DcpBackendReader
Handler: lambda-function.lambda_handler
Runtime: python3.9
CodeUri: src/dcpBackendReader/
Description: Lambda function for reading from the database
Tags:
env: "3"
serviceGroup: "2"
owner: "1"
MemorySize: 128
Timeout: 15
Layers:
- !Ref DcpDbManagementLayer
- arn:aws:lambda:us-east-1:acc-id:layer:pymysql:1
Role: !GetAtt DcpBackendReaderRole.Arn
VpcConfig:
SecurityGroupIds:
- sg-123456789xxxxxxxx
SubnetIds:
- subnet-0012345678910xxxx
- subnet-00123456789xxxxxx
Environment:
Variables:
DB_HOST: aurora-host.us-east-1.rds.amazonaws.com
SM_DNS: https://vpce-12345678910111213x-12345678.secretsmanager.us-east-1.vpce.amazonaws.com
DB_SM_KEY: secrets/manager/key/for/user/and/pss
DB_SM_REGION: us-east-1
DcpBackendWriterFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: DcpBackendWriter
Handler: lambda-function.lambda_handler
Runtime: python3.9
CodeUri: src/dcpBackendWriter/
Description: Lambda function for writing to the database
Tags:
env: "3"
serviceGroup: "2"
owner: "1"
MemorySize: 128
Timeout: 15
Layers:
- !Ref DcpDbManagementLayer
- arn:aws:lambda:us-east-1:acc-id:layer:pymysql:1
Role: !GetAtt DcpBackendWriterRole.Arn
VpcConfig:
SecurityGroupIds:
- sg-123456789xxxxxxxx
SubnetIds:
- subnet-0012345678910xxxx
- subnet-00123456789xxxxxx
Environment:
Variables:
DB_HOST: aurora-host.us-east-1.rds.amazonaws.com
SM_DNS: https://vpce-12345678910111213x-12345678.secretsmanager.us-east-1.vpce.amazonaws.com
DB_SM_KEY: secrets/manager/key/for/user/and/pss
DB_SM_REGION: us-east-1
DcpServerlessApiGtw:
Type: AWS::Serverless::Api
Properties:
Name: DcpServerlessApiGtw
StageName: prod
MethodSettings:
- ResourcePath: '/*'
HttpMethod: '*'
LoggingLevel: INFO
DataTraceEnabled: true
MetricsEnabled: true
AccessLogSetting:
Format: '{ "requestId":"$context.requestId", "ip": "$context.identity.sourceIp", "caller":"$context.identity.caller", "user":"$context.identity.user", "requestTime":"$context.requestTime", "httpMethod":"$context.httpMethod", "resourcePath":"$context.resourcePath", "status":"$context.status", "protocol":"$context.protocol", "responseLength":"$context.responseLength" }'
DestinationArn: !GetAtt DcpApiGatewayLogGroup.Arn
DefinitionBody:
openapi: 3.0.1
info:
title: DCP API Gateway
version: '1.0'
Policy:
Statement:
- Effect: Allow
Principal:
Service: apigateway.amazonaws.com
Action: lambda:InvokeFunction
Resource:
- !Sub 'arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:DcpBackendReader'
- !Sub 'arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:DcpBackendWriter'
Condition:
StringEquals:
aws:SourceDomain: https://vpce-12345678910111213x-12345678.execute-api.us-east-1.vpce.amazonaws.com
paths:
/{database_name}/{table_name}:
get:
x-amazon-apigateway-integration:
httpMethod: GET
type: aws_proxy
uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${DcpBackendReaderFunction.Arn}/invocations
responses: {}
post:
x-amazon-apigateway-integration:
httpMethod: POST
type: aws_proxy
uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${DcpBackendWriterFunction.Arn}/invocations
responses: {}
put:
x-amazon-apigateway-integration:
httpMethod: PUT
type: aws_proxy
uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${DcpBackendWriterFunction.Arn}/invocations
responses: {}
/{database_name}/{table_name}/{id}:
get:
x-amazon-apigateway-integration:
httpMethod: GET
type: aws_proxy
uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${DcpBackendReaderFunction.Arn}/invocations
responses: {}
delete:
x-amazon-apigateway-integration:
httpMethod: DELETE
type: aws_proxy
uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${DcpBackendWriterFunction.Arn}/invocations
responses: {}
Outputs:
DcpDbManagementLayerVersion:
Description: DCP Database Management Layer version ARN
Value: !Ref DcpDbManagementLayer
DcpServerlessApiGtwUrl:
Description: DCP API Gateway URL
Value: !Sub https://${DcpServerlessApiGtw}.execute-api.${AWS::Region}.amazonaws.com/prod`
基本上尝试了上面提到的所有内容,但什么都没有,为什么这不起作用的任何想法?
我没有使用最佳实践,因为我仍将更新安全规则并实施身份验证,目前此应用程序没有任何敏感数据,我只是想部署它并测试基础是否有效,但事实并非如此:(
你的
httpMethod
对象中的 x-amazon-apigateway-integration
必须始终是 POST
.
这是 API 网关与您的数据源而非您的客户端之间集成的动词。
集成请求中使用的 HTTP 方法。对于 Lambda 函数调用,该值必须是 POST。
将
GET
、PUT
和DELETE
替换为POST
。
在此文档页面中查找
httpMethod
: