Combination of AWS API Gateway and Lambda functions is a flag example of every “serverless infrastructure”. When deploying API Gateway with CloudFormation there are two different ways you can define your API: via Swagger template or by directly defining your methods in CloudFormation template.
For API Gateway you need at least 3 basic elements:
- AWS::ApiGateway::RestApi
- AWS::ApiGateway::Deployment
- AWS::ApiGateway::Stage
If you want to find out more about what each of those are, check out APIGateway documentation.
To use a Swagger template, simply use the BodyS3Location
parameter on the AWS::ApiGateway::RestApi
.
To automatically connect your API calls to the Lambda backend, you’ll need to include additional information inside your Swagger file – a x-amazon-apigateway-integration
object, documented here: AWS documentation on x-amazon-apigateway-integration.
If you’re defining the methods and resources within CloudFormation template, you need to define the following objects: AWS::ApiGateway::Resource
and AWS::ApiGateway::Method
.
For an example simple integration, where API Gateway methods are defined within the CloudFormation template, see:
Using troposphere: apigateway_with_lambda.py
Final JSON template: apigateway_with_lambda.json
To make API Gateway work with a Lambda function, you need to define the Lambda with its role (as needed) and a permission (AWS::Lambda::Permission
) for API Gateway to execute your Lambda.
Example of defining the permission:
from troposphere import awslambda awslambda.Permission( "APILambdaPermission", Action="lambda:InvokeFunction", FunctionName=..., Principal="apigateway.amazonaws.com", SourceArn=Join("", [ "arn:aws:execute-api:", Ref("AWS::Region"), ":", Ref("AWS::AccountId"), ":", Ref(api), "/*/GET/*" ]) )
The same as CloudFormation JSON:
"APILambdaPermission": { "Properties": { "Action": "lambda:InvokeFunction", "FunctionName": ..., "Principal": "apigateway.amazonaws.com", "SourceArn": { "Fn::Join": [ "", [ "arn:aws:execute-api:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "API" }, "/*/GET/*" ] ] } }, "Type": "AWS::Lambda::Permission" }
Because neither Ref
nor GetAtt
functions can return an ARN for an API Gateway element, you have to build it yourself within the template. It follows this structure:
arn:aws:execute-api:REGION:ACCOUNT_ID:API_ID:API_STAGE:HTTP_METHOD:RESOURCE
In the example above, we allow the Lambda to pass any GET calls to any stage of the API to any resource within the API. You can obviously modify those as needed.
For a full working example of a working application, check out this stack using troposphere: Image Gateway API.
yugesh
blank page error when clicking api enpointurl, only show blank page
Paulina Budzon
Hi yugesh!
No sure what you’re refering to – an example from the post, or your own implementation? I’m happy to help either way, but a bit more detail would help π
yugesh
by clicking the endpoint url of api deployed from cloudformation it shows empty page, i have used your code for deployment
Paulina Budzon
Hi yugesh,
If you use an inspector in your browser or a command-line tool like curl, can you see what response code you’re getting? If you used the example code (from github), it would have asked you to provide a source code for your Lambda (S3 bucket and a Lambda source file/package in that bucket). You’re mosty likely to find an error logged in this Lambda logs – also, check that this Lambda gets executed correctly. If you want to debug in API Gateway directly, you can use the “test” feature in API Gateway console as well, this will show you exactly what’s happening when a request comes in.
Hope this helps!
yugesh
it does not support GET method
Paulina Budzon
Hi yugesh. That’s correct. This piece of code is just an example, and I wanted to keep it as short as possible to avoid clouding what’s going on. I chose to show a POST method as an example, since those generally have a payload, which is another setting in API Gateway. If I chose GET or DELETE for the example I couldn’t have shown how to configure the payload details π Hope this helps!
yugesh
how can i deploy multiple lambda in one cloudformation stack
Paulina Budzon
Hi yugesh.
You can have multiple
AWS::Lambda::Function
resources in one template. If you’re using the example above, you can have more parameters like theLambdaFileName
to specify the source code for each Lambda. It’s generally a good idea to have separate roles and permissions for each Lambda as well to better control access to Lambda and other resources.You can take a look at this template as well. It’s a bit messy and injects Lambda source directly into CloudFormation template (which makes it easier if your Lambdas are quite short) and it specifies three Lambdas:
LambdaBaseFunction
,LambdaReleaseFunction
andLambdaCleanESFunction
.Hope this helps!
yugesh
how can we trigger multiple lambda function with one api gateway
sakunthala
Hi,
Could you say if there is a way to generate swagger docs for the apis exposed by Api gateway
Paulina Budzon
Hi sakunthala,
The procedure of exporting the API is swagger and other formats is documented here: https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-export-api.html
If you’d like to do that from the console (not from an api call), there’s instructions at the end where to find the button in the console.