У меня есть лямбда-функция, которая будет обрабатывать запросы PUT и GET, используя Amazon API Gateway {proxy +} .
Он работает правильно, когда все настройки устанавливаются вручную с помощью консоли Amazon. но я хочу автоматизировать его с помощью AWS Cloudformation.
Чтобы сообщить вам, я напишу шаги для установки {proxy+}
:
1) создайте простую лямбда-функцию и вставьте в нее следующие строки кода:
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
и нажмите Save
8) во всплывающем окне Add Permission to Lambda Function
нажмите Ok
9) из Actions
нажмите Deploy API
10) Выберите New Stage
из списка для Deployment stage
, затем введите имя для Stage name
(для меня я набрал 'api') и нажмите Deploy
11) на stage
на корневой странице развернутого API вы можете увидеть Invoke URL
. щелкните по нему, и он откроет новую вкладку, связанную где-то вроде этого: https://xxxxxxxxx.execute -api.us-east-1.amazonaws.com / api /
12) добавьте простой сегмент в конец вашего URL следующим образом:
https://xxxxxxxxx.execute -api.us-east-1.amazonaws.com / апи / тест
теперь вы должны увидеть ниже сообщение на странице вашего браузера:
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"}
Подскажите, пожалуйста, что не так и как я могу решить проблему?