This repo is an AWS Lambda serverless app template with Terraform deployment management. It is intended to guide you to good choices for ease of development and operations, without being overly opinionated about your workflow.
AWS Lambda is a serverless application platform that we use to build web applications, services/APIs, and event handlers on AWS. Lambda scales quickly to accommodate burst loads, and integrates tightly with many AWS event sources, allowing us to build simpler, more efficient and maintainable applications on AWS.
Terraform is an Infrastructure-as-Code framework that we use to manage our cloud resources. Terraform allows us to automatically, reproducibly, and securely manage our AWS infrastructure.
Out of the box, Terraform and Lambda require a lot of configuration and domain knowledge to work together. You need to know how to package your function and its dependencies, configure its IAM role, set up event sources, configure API Gateway, set up a Terraform credentials source and state backend, and more, depending on your application.
In this repository, we provide the tools to take care of all this in a minimalistic, well-documented, intuitive way, so you can focus on building your app.
To manage the Lambda packaging, we use Chalice, a Python microframework developed by
AWS for Lambda. The template in this repo builds upon the output of chalice new-project
.
Instead of letting Chalice directly deploy our app, we run chalice package
, which builds the app and produces
a Terraform module, chalice.tf.json
. We then use Terraform to deploy the app from this module.
We also provide a recipe to easily manage Terraform credentials and state on AWS. The AWS API credentials are imported on demand from your AWS CLI config, which allows you to centrally manage your credentials, Assume Role configurations, and regions using standard AWS conventions. Terraform state files are saved using the Terraform S3 backend, keyed by your app name.
To deploy the app, type make deploy
in this directory.
Filename | Purpose | Information links |
---|---|---|
app.py |
The application entry point | Chalice Docs |
requirements-dev.txt |
Developer environment dependencies | Pip requirements files |
requirements.txt |
Application dependencies | Chalice App Packaging |
Makefile |
Tools for packaging and deploying | Automation and Make |
.chalice/config.json |
Chalice config file for the app | Chalice Configuration File |
.chalice/policy-dev.json |
IAM policy for the app's IAM role | Lambda Permissions |
test/test.py |
Test suite template | Python unittest |
.travis.yml |
Travis CI (CI/CD) configuration | Travis CI |
- Install the dependencies:
pip install -r requirements-dev.txt
and Terraform (brew install terraform
or https://www.terraform.io/downloads.html) - Configure the AWS CLI (
pip install awscli
;aws configure
). - Ensure the S3 bucket
tfstate-<YOUR_AWS_ACCOUNT_ID>
exists, or modify the Makefile to reference a different bucket. - Fork or copy the contents of this repo to a new directory.
- Edit
.chalice/config.json
to set the name of your app and Lambda settings like memory, timeout, reserved concurrency, tags, and environment variables. - Edit
app.py
andrequirements.txt
to create your app. - Deploy your app by running
make deploy
. The deployment results, including your Lambda's EndpointURL, will be printed to the terminal. You can immediately test your app by running (for example)http https://your-api-id.execute-api.us-east-1.amazonaws.com/api/
or opening the EndpointURL in a browser. - If needed, assign
a Custom Domain Name,
ACM certificate and Route 53 CNAME
to your app in the API Gateway AWS Console,
so users can reach your app on a friendly domain like
https://app.czi.technology
.
To redeploy your app after updating, run make deploy
again. To undeploy the app and delete all associated resources,
run make destroy
.
The test suite in test/test.py
runs Chalice in local mode for unit testing. You can invoke it using make test
. This
test is also configured to run on Travis CI.
Your Lambda function is assigned an IAM role that controls the permissions given to the Lambda's AWS credentials. This
IAM role is set from the file .chalice/policy-dev.json
. Edit this policy and repeat the deployment if your Lambda
needs access to other AWS APIs. You can also edit the Makefile to parameterize this file or generate it from a template
as needed. (The setting autogen_policy
must be set to false
in .chalice/config.json
for Chalice to use this file.)
See Lambda Event Sources in the Chalice docs for details on how to connect your app to other AWS event sources. If the built-in event handlers are not sufficient, you could also consider using the Domovoi project, which builds upon Chalice to handle many other event source configurations (but is not currently compatible with the Terraform workflow shown here).
Lambda is automatically set up to emit logs to
CloudWatch Logs, which you can
browse in the AWS console by selecting the log group for your
Lambda. You can see built-in CloudWatch metrics (invocations, errors, etc.) by selecting your Lambda in the
Lambda AWS console and going to the Monitoring tab.
To tail and filter logs on the command line, you can use the logs
command in the
Aegea package, for example:
aegea logs /aws/lambda/my-lambda-APIHandler-ABCDEXAMPLE --start-time=-15m