Skip to content

Instantly share code, notes, and snippets.

@magnetikonline
Last active March 30, 2024 06:24
Show Gist options
  • Star 54 You must be signed in to star a gist
  • Fork 15 You must be signed in to fork a gist
  • Save magnetikonline/c314952045eee8e8375b82bc7ec68e88 to your computer and use it in GitHub Desktop.
Save magnetikonline/c314952045eee8e8375b82bc7ec68e88 to your computer and use it in GitHub Desktop.
CloudFormation API Gateway endpoint calling a Lambda function using proxy integration example.

CloudFormation API Gateway integration to Lambda function

Template that will create the following:

  • API Gateway:
    • Deployed as a REGIONAL endpoint.
    • Single root method, accepting POST requests only, with Lambda proxy integration to a target function.
  • In-line Python Lambda function echoing back requesting users IP address to API Gateway requests:
    • IAM role for Lambda allowing CloudWatch logs access.
    • Permissions for Lambda that allow API Gateway endpoint to successfully invoke function.
  • CloudWatch logs group for Lambda, with 90 day log retention.

After standing up the template, you will be able to make a HTTP POST request to the URL listed as the apiGatewayInvokeURL output value.

$ curl --request POST https://APIGW_ID.execute-api.AWS_REGION.amazonaws.com/call
# Hello there 127.0.0.1

Reference

AWSTemplateFormatVersion: 2010-09-09
Description: My API Gateway and Lambda function
Parameters:
apiGatewayName:
Type: String
Default: my-api
apiGatewayStageName:
Type: String
AllowedPattern: '[a-z0-9]+'
Default: call
apiGatewayHTTPMethod:
Type: String
Default: POST
lambdaFunctionName:
Type: String
AllowedPattern: '[a-zA-Z0-9]+[a-zA-Z0-9-]+[a-zA-Z0-9]+'
Default: my-function
Resources:
apiGateway:
Type: AWS::ApiGateway::RestApi
Properties:
Description: Example API Gateway
EndpointConfiguration:
Types:
- REGIONAL
Name: !Ref apiGatewayName
apiGatewayRootMethod:
Type: AWS::ApiGateway::Method
Properties:
AuthorizationType: NONE
HttpMethod: !Ref apiGatewayHTTPMethod
Integration:
IntegrationHttpMethod: POST
Type: AWS_PROXY
Uri: !Sub
- arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${lambdaArn}/invocations
- lambdaArn: !GetAtt lambdaFunction.Arn
ResourceId: !GetAtt apiGateway.RootResourceId
RestApiId: !Ref apiGateway
apiGatewayDeployment:
Type: AWS::ApiGateway::Deployment
DependsOn:
- apiGatewayRootMethod
Properties:
RestApiId: !Ref apiGateway
StageName: !Ref apiGatewayStageName
lambdaFunction:
Type: AWS::Lambda::Function
Properties:
Code:
ZipFile: |
def handler(event,context):
return {
'body': 'Hello there {0}'.format(event['requestContext']['identity']['sourceIp']),
'headers': {
'Content-Type': 'text/plain'
},
'statusCode': 200
}
Description: Example Lambda function
FunctionName: !Ref lambdaFunctionName
Handler: index.handler
MemorySize: 128
Role: !GetAtt lambdaIAMRole.Arn
Runtime: python3.8
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
@uchar
Copy link

uchar commented Apr 7, 2019

I think
SourceArn: !Sub "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${apiGateway}/*/POST/"
should be :
SourceArn: !Sub "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:my-api/*/POST/"

@aghalbert
Copy link

Tested @uchar's comment, the change causes an {"message": "Internal server error"} response, so the original value is correct.

@nankan06
Copy link

I am facing an error in AWS::ApiGateway::Deployment. The error is,
'Encountered unsupported property RestApiID'. Any help please?

@jhw
Copy link

jhw commented Jun 5, 2019

My guess is u have RestApiID probably badly indented, probably under Integration when it should be under Properties - I did the same

@bmschwa
Copy link

bmschwa commented Jul 11, 2019

When running

sam local start-api --debug

sam believes there's no apis connected to the lambda function (using sam 0.18.0)

@cam8001
Copy link

cam8001 commented Dec 2, 2019

@manigct10
Copy link

by using this template, i am getting {"message":"Missing Authentication Token"}
because integration response is not enabled, please solve this issue

@manigct10
Copy link

tell me how to add integration response to get the response from lambda

@vijeur
Copy link

vijeur commented Jul 19, 2021

@manifct10 you might testing using browser, try from command line (terminal) as stated in the beginning of this page $ curl --request POST https://APIGW_ID.execute-api.AWS_REGION.amazonaws.com/call
response would be Hello there 127.0.0.1 (your IP)

@asulyma
Copy link

asulyma commented Oct 6, 2021

Thanks, this solution is still working correctly!

Notes:

  • I've created lambda based on the docker image - everything works fine;
  • Be careful with AuthorizationType, perhaps you don't need to make it as NONE;
  • if you will change apiGatewayHTTPMethod after deploy - you catch the expected exception, solution: needs to delete your cloud formation at all and re-create again.

@magnetikonline
Copy link
Author

nice one @Aleksandr04 👍

@donsamiro
Copy link

Can you make an example with PATH_PART please? I do something wrong but I don't see the issue. I need multiple ressources and paths.

Structure is for example:

root:
--------> application
|
|--------------> rule

Thanks in advance

@shadyyehia
Copy link

I get a validationError "Unresolved resource dependencies [lambdaArn] in the Resources block of the template" , anyone could resolve this ?

@guidocaru
Copy link

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment