我有一个lambda函数,它将使用Amazon API Gateway {proxy+}处理PUT和GET请求。 通过Amazon Console手动设置所有设置后,它可以正常工作。但是我想使用AWS Cloudformation使其自动化。
为了通知您,我将写出设置{proxy+}
的步骤:
1)创建一个简单的Lambda function并将以下代码行粘贴到其中:
import boto3
def lambda_handler(event, context):
return {
"statusCode": 200,
"headers": {
"Content-Type": 'text/html',
"Access-Control-Allow-Origin": "*"
},
"body": "Hello Reza Amya, Your Lambda is working..!"
}
2)转到Amazon API Gateway,然后单击Create API
。
3)选择New API
,填充API name
,从Edge optimized
的列表中选择Endpoint Type
,然后单击Create API
4)然后创建您的API,您应该在其Resources
页面上,否则请转到Resources
页面以创建API。
5)从Actions
中选择Create Resource
6)选择Configure as proxy resource
(然后它应该自动更改其他字段,如果没有更改,请为proxy
输入Resource Name
,为{proxy+}
输入Resource Path
),然后点击Create Resource
7)为Lambda Function Proxy
选择Integration type
,然后从Lambda Function
中选择您的lambda函数,然后单击Save
8)在Add Permission to Lambda Function
弹出窗口中,单击Ok
9)从Actions
单击Deploy API
10)从New Stage
的列表中选择Deployment stage
,然后为Stage name
键入一个名称(对我来说,我输入了'api'),然后单击Deploy
< / p>
11)在已部署API的根页面上的stage
上,您可以看到Invoke URL
。单击它,它将打开链接到类似以下位置的新标签:https://xxxxxxxxx.execute-api.us-east-1.amazonaws.com/api/
12)在您的网址末尾添加一个简单的段,如下所示: https://xxxxxxxxx.execute-api.us-east-1.amazonaws.com/api/ 测试
现在您应该在浏览器页面中看到以下消息:
Hello Reza Amya, Your Lambda is working..!
现在的问题是我已经在Yaml文件中编写了所有这些步骤:
AWSTemplateFormatVersion: 2010-09-09
Description: My Lambda Function
Parameters:
S3Bucket:
Description: S3 Bucket where the Lambda code is
Type: String
S3Key:
Description: S3 Key where the Lambda code is
Type: String
S3ObjectVersion:
Description: Version of the S3 Key to use
Type: String
Resources:
apiGateway:
Type: "AWS::ApiGateway::RestApi"
Properties:
Name: "my-api"
Description: "My API"
EndpointConfiguration:
Types:
- EDGE
Resource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId:
Ref: "apiGateway"
ParentId:
Fn::GetAtt:
- "apiGateway"
- "RootResourceId"
PathPart: "{proxy+}"
ProxyMethod:
Type: 'AWS::ApiGateway::Method'
Properties:
HttpMethod: ANY
ResourceId: !Ref Resource
RestApiId: !Ref apiGateway
AuthorizationType: NONE
RequestParameters:
method.request.path.proxy: true
Integration:
CacheKeyParameters:
- 'method.request.path.proxy'
RequestParameters:
integration.request.path.proxy: 'method.request.path.proxy'
Type: AWS_PROXY
IntegrationHttpMethod: ANY
Uri: !Sub
- arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${Arn}/invocations
- Arn:
Fn::GetAtt:
- LambdaFunction
- Arn
PassthroughBehavior: WHEN_NO_MATCH
IntegrationResponses:
- StatusCode: 200
apiGatewayDeployment:
Type: "AWS::ApiGateway::Deployment"
DependsOn:
- "ProxyMethod"
Properties:
RestApiId: !Ref "apiGateway"
StageName: "dev"
IAMRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: 'sts:AssumeRole'
Policies:
- PolicyName: Logging
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- 'logs:CreateLogGroup'
- 'logs:CreateLogStream'
- 'logs:PutLogEvents'
Resource: 'arn:aws:logs:*:*:*'
- PolicyName: AccessToDynamoDB
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- 'dynamodb:CreateTable'
- 'dynamodb:DeleteItem'
- 'dynamodb:DeleteTable'
- 'dynamodb:GetItem'
- 'dynamodb:GetRecords'
- 'dynamodb:UpdateItem'
- 'dynamodb:UpdateTable'
- 'dynamodb:PutItem'
- 'dynamodb:UpdateTable'
Resource: 'arn:aws:dynamodb:*:*:*'
LambdaFunction:
Type: AWS::Lambda::Function
Properties:
Code:
S3Bucket: {Ref: S3Bucket}
S3Key: {Ref: S3Key}
S3ObjectVersion: {Ref: S3ObjectVersion}
Handler: main.lambda_handler
MemorySize: 128
Role: {'Fn::GetAtt': [IAMRole, Arn]}
Runtime: python3.6
Timeout: 300
LambdaInvokePermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !GetAtt
- LambdaFunction
- Arn
Action: 'lambda:InvokeFunction'
Principal: apigateway.amazonaws.com
SourceArn: !Sub arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${apiGateway}/*/*
Outputs:
apiGatewayInvokeURL:
Value: !Sub "https://${apiGateway}.execute-api.${AWS::Region}.amazonaws.com/${apiGateway}"
lambdaArn:
Value: !GetAtt "LambdaFunction.Arn"
上面的Yaml文件将创建Lambda函数并部署API,但是当我尝试测试API时,它将显示以下错误:
{"message": "Internal server error"}
能否请您指导我哪里出了问题以及如何解决该问题?
答案 0 :(得分:2)
问题与您的IntegrationHttpMethod
设置有关。尽管您的APIGateway方法为ANY
,但对于AWS Lambda,IntegrationHttpMethod
必须始终为POST
。
这将导致以下方法声明。
ProxyMethod:
Type: 'AWS::ApiGateway::Method'
Properties:
HttpMethod: ANY
ResourceId: !Ref Resource
RestApiId: !Ref apiGateway
AuthorizationType: NONE
RequestParameters:
method.request.path.proxy: true
Integration:
CacheKeyParameters:
- 'method.request.path.proxy'
RequestParameters:
integration.request.path.proxy: 'method.request.path.proxy'
Type: AWS_PROXY
IntegrationHttpMethod: POST
Uri: !Sub
- arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${Arn}/invocations
- Arn:
Fn::GetAtt:
- LambdaFunction
- Arn
PassthroughBehavior: WHEN_NO_MATCH
IntegrationResponses:
- StatusCode: 200