For last couple of day's I am working on cloud formation template which will create a API Gateway hooked up with a lambda behind it, The APIGW will just have a {proxy+} resource with an ANY method and I want to handle all the logic in the backend lambda.
I was able to create the same via console :

Now I want to replicate the same via cloud formation template My current CloudFormation template
AWSTemplateFormatVersion: 2010-09-09
Description: My API Gateway and Lambda function
Parameters:
apiGatewayName:
Type: String
Default: proxy-apigw
apiGatewayStageName:
Type: String
Default: v1
apiGatewayHTTPMethod:
Type: String
Default: ANY
lambdaFunctionName:
Type: String
AllowedPattern: "[a-zA-Z0-9]+[a-zA-Z0-9-]+[a-zA-Z0-9]+"
Default: proxy-lambda
Resources:
apiGateway:
Type: AWS::ApiGateway::RestApi
Properties:
Description: Example API Gateway
EndpointConfiguration:
Types:
- REGIONAL
Name: !Ref apiGatewayName
apiGatewayLambdaResource:
Type: 'AWS::ApiGateway::Resource'
Properties:
RestApiId: !Ref apiGateway
PathPart: '{proxy+}'
ParentId: !GetAtt apiGateway.RootResourceId
apiGatewayLambdaResourceMethod:
Type: 'AWS::ApiGateway::Method'
Properties:
AuthorizationType: NONE
RestApiId: !Ref apiGateway
ResourceId: !Ref apiGatewayLambdaResource
HttpMethod: ANY
Integration:
Type: AWS_PROXY
IntegrationHttpMethod: POST
Uri: !Sub
- >-
arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${lambdaArn}/invocations
- lambdaArn: !GetAtt lambdaFunction.Arn
MethodResponses:
- StatusCode: 200
ResponseModels: { "application/json": "Empty" }
apiGatewayDeployment:
Type: AWS::ApiGateway::Deployment
DependsOn:
- apiGatewayLambdaResourceMethod
Properties:
RestApiId: !Ref apiGateway
StageName: !Ref apiGatewayStageName
lambdaFunction:
Type: AWS::Lambda::Function
Properties:
Code:
ZipFile: |
exports.handler = async (event) => {
// TODO implement
const response = {
statusCode: 200,
body: JSON.stringify(event),
};
return response;
};
Description: Example Lambda function
FunctionName: !Ref lambdaFunctionName
Handler: index.handler
Role: !GetAtt lambdaIAMRole.Arn
Runtime: nodejs12.x
lambdaApiGatewayInvoke:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !GetAtt lambdaFunction.Arn
Principal: apigateway.amazonaws.com
# note: if route *not* at API Gateway root, `SourceArn` would take the form of:
# arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${apiGateway}/${apiGatewayStageName}/${apiGatewayHTTPMethod}/PATH_PART
SourceArn: !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${apiGateway}/${apiGatewayStageName}/${apiGatewayHTTPMethod}/
lambdaIAMRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Action:
- sts:AssumeRole
Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Policies:
- PolicyDocument:
Version: 2012-10-17
Statement:
- Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Effect: Allow
Resource:
- !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${lambdaFunctionName}:*
PolicyName: lambda
lambdaLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub /aws/lambda/${lambdaFunctionName}
RetentionInDays: 90
Outputs:
apiGatewayInvokeURL:
Value: !Sub https://${apiGateway}.execute-api.${AWS::Region}.amazonaws.com/${apiGatewayStageName}
lambdaArn:
Value: !GetAtt lambdaFunction.Arn
With this I was able to create a {proxy+} resource under the root and a ANY method associated with the /{proxy+} resource, but when I call APIGW URL I am getting internal server error
patelnab@3c22fb980312 ~ % curl --request GET https://nx9gwoz5de.execute-api.us-east-1.amazonaws.com/v1/test/route
{"message": "Internal server error"}%
This is APIGW looks, which is got created by Cloudformation template

One difference, I was able to point out is in Method Response, The one I created via console has HTTP Status: Proxy where as the which was created via CloudFormation doesn't have that. I tried searching in the documentation but could not find much on this. Any help on this is highly appreciated
Your permissions are incorrect. You are missing /*:
lambdaApiGatewayInvoke:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !GetAtt lambdaFunction.Arn
Principal: apigateway.amazonaws.com
# note: if route *not* at API Gateway root, `SourceArn` would take the form of:
# arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${apiGateway}/${apiGatewayStageName}/${apiGatewayHTTPMethod}/PATH_PART
SourceArn: !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${apiGateway}/${apiGatewayStageName}/${apiGatewayHTTPMethod}/*
And if you want to polulate MethodRequest, you can do:
Integration:
Type: AWS_PROXY
IntegrationHttpMethod: POST
Uri: !Sub
- >-
arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${lambdaArn}/invocations
- lambdaArn: !GetAtt lambdaFunction.Arn
IntegrationResponses:
- ResponseTemplates:
application/json: ""
StatusCode: 200
PassthroughBehavior: WHEN_NO_TEMPLATES
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With