This project serves as a reference, serverless application using AWS services:
- API Gateway
- with endpoint authentication via Lambda Authorizer
- with an OpenAPI specification made publicly available
- CloudFront (for caching the frontend API)
- Lambda
- DynamoDB
- NuxtJS frontend
- SAM/CloudFormation IaC
- CI/CD
integration-tests/
- this contains post-deploy integration tests written in NodeJS.templates/
- this directory contains the CloudFormation IaC that will be used to define the application. It's designed in a nested stack manner, with thetemplates/main.yml
being the parent stack and everything else nested underneath it.src/node/
- this is the root directory for all lambda handlers written in NodeJS.src/python/
- this is the root directory for all lambda handlers written in Python.src/frontend/
- this is the root directory for the frontend codeload-tests/
- this directory contains Artillery scripts and configuration to run load tests against the applicationopenapi/
- this directory contains assets that can be used to render the OpenAPI editor, useful to view and validate your OpenAPI documentation.
The frontend is designed with Server Side Rendering (SSR) in mind. This is using the NuxtJS framework to handle rendering the application. The compute that handles the rendering is AWS Lambda, sitting behind API Gateway.
The backend includes examples of serverless functions using both NodeJS and Python runtimes:
src/node/
src/python/
Most of this project is written in NodeJS. A Python Hello, world
Lambda is provided for reference.
Makefiles are used throughout the project to handle defining various development workflow commands that need to be run throughout CI/CD. This includes running unit tests, building code, deployment, and integration tests.
The following "CI/CD" entrypoints are defined:
unit-test
- iterate through everysrc/
directory running tests for each application code component (frontend, backend node, and backend python). Eachsrc/
directory defines its ownMakefile
with atest
target to prepare and run tests for that given codebuild
- iterate through everysrc/
directory, performing any required build steps of that code (frontend, backend node, and backend python). Eachsrc/
directory defines its ownMakefile
with abuild
target to build code. Afterwards, the rootMakefile
will runsam build
on thetemplates/main.yml
file. Finally, it will runsam package
on the built directory fromsam build
, uploading all code to the S3 bucket specified by theS3_BUCKET
variable. Anartifacts/main.packaged.yml
will be produced thatdeploy
- deploys the producedartifacts/main.packaged.yml
file.integration-test
- iterate through*.test.js
integration test files in theintegration-tests/
directory.
CI/CD will depend on the following variables:
APPLICATION_NAME
- the name of the application you're deployingENVIRONMENT_NAME
- the name of the environment you're deploying toS3_BUCKET
- the name of the bucket you'd like to upload code artifacts toDEVOPS_ACCOUNT_ID
- the AWS account ID that contains the artifact bucketDEV_ACCOUNT_ID
- the AWS account ID that should receive the dev environmentQA_ACCOUNT_ID
- the AWS account ID that should receive the QA environmentPROD_ACCOUNT_ID
- the AWS account ID that should receive the production environment
AWS IAM access is handled via IAM roles. This uses the aws-actions/configure-aws-credentials
action to get credentials from an OIDC provider. To learn more about that, check out this article.
The templates/
directory contains SAM/CloudFormation templates which define cloud resources. A root stack is defined in templates/main.yml
, which houses multiple, nested stacks.
Requisite variable inputs are provided via the Makefile. When triggered via CI/CD, these variable inputs are already configured. When triggering locally, you will be required to pass the -e
flag to certain make
commands:
ENVIRONMENT_NAME
This project:
- Uses SAM, the AWS Servesless Applicaiton Model. SAM abstracts and simplifies the creation of serverless toolsets, as defined in
templates/*.yml
files. - Stubs out a custom Lambda Authorizer function, which will need further developed to integrate with your IdP
- Explicitly defines an OpenAPI spec and makes that spec publicly available via the
/docs
endpoint