Skip to content

rynop/abp-single-lambda-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

63 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

abp-single-lambda-api

aws-blueprint example for an API backed by a single lambda

Each branch of this repo is a different language for the same example app.

Single lambda

This example sets up a CI/CD for a single lambda, fronted by CloudFront and API Gateway.

Setup

  1. Run the setup script from your local git repo dir:

    wget -q https://raw.githubusercontent.com/rynop/abp-single-lambda-api/master/bin/setup.sh; bash setup.sh; rm setup.sh
    

    This:

    • Downloads the branch of of your favorite programming language, and common aws dir out of master branch.
    • Sets NestedStacksS3Bucket and s3 versions of your nested-stacks in your resources CloudFormation file.
  2. Create a s3 bucket that will hold your lambda zips. Only need one bucket per AWS. Ex: deploy.yourdomain.com

  3. Create your "resources" (CloudFront, API Gateway etc) stacks using aws/cloudformation/cf-apig-single-lambda-resources.yaml in your repo. Stack naming convention is [stage]--[repo]--[branch]--[eyecatcher]--r. Ex: prod--abp-single-lambda-api--master--ImageManip--r:

    • Create a stack for your test and prod stages. You will have 2 root stacks. The prod stack takes care of both prod and staging resources.
    • The Outputs tab in the CloudFormation UI for each root stack has commands you will run in the next steps. Outputs that start with Run* you should run from your CLI.
  4. Some of the Lambda configuration is stored in Systems manager parameter store with the convention based prefix /<stage>/<repoName>/<branch>/<lambdaName>/. Ex: aws ssm put-parameter --name "/prod/abp-single-lambda-api/master/ResizeImage/lambdaExecutionRoleArn" --type "String" --value 'arn:aws:iam::accountId:role/roleName'. These keys are required per stage:

    • /<stage>/<repoName>/<branch>/<lambdaName>/lambdaExecutionRoleArn (don't create for staging stage. staging uses the prod lambdaExecutionRoleArn). The output of the Resources CloudFormation stack contains a SsmSetLambdaExecutionRoleCmd value that is an aws CLI command that sets this for you.
    • /<stage>/<repoName>/<branch>/<lambdaName>/lambdaTimeout
    • /<stage>/<repoName>/<branch>/<lambdaName>/lambdaMemory
    • /<stage>/<repoName>/<branch>/<lambdaName>/vpcConfig. Optional. If your lambda needs to be in vpc, value should be like SubnetIds=string,string,SecurityGroupIds=string,string. See AWS CLI docs for more info.
  5. Setup env vars per stage. All keys in the lambdaEnvs namespace are automatically added your your lambda's env. They can optionally be encrypted in systems manager param store, we handle all the decoding complexity (if you use the default KMS key). You can use this script help set them.

    • /<stage>/<repoName>/<branch>/<lambdaName>/lambdaEnvs/<env var name>. Ex: /prod/abp-single-lambda-api/master/ResizeImage/lambdaEnvs/MY_VAR
    • Run the SsmSetXFromCdnEnvVarCmd output value from the Resources CloudFormation stack. It sets X_FROM_CDN (used by the example code in this repo).
    • These env vars get set for your in the lambda configuration: APP_STAGE
  6. Create a Github user (acct will just be used to read repos for CI/CD), give it read auth to your github repo. Create a personal access token for this user at https://github.com/settings/tokens. This token will be used by the CI/CD to pull code.

  7. Go through the README.md of the language branch you copied, language specific setup and for stack parameter values that will be used in CI/CD stack creation (next step).

  8. Create a CloudFormation stack for your CI/CD using single-lambda-test-staging-prod.yaml with the stack naming convention of [repo]--[branch]--[eyecatcher]--cicd. Ex: abp-single-lambda-api--master--ResizeImage--cicd.

  9. Commit your code and the CI/CD CodePipline will automatically run. The buildspec files assume you check in your dependencies (aka node_modules). Prevents version issues when working in teams, also prevents deploy issues during github outage.

  10. The domain your app can be reached, is located in the Outputs tab of the resources CloudFormation stack at key CNAME.

  11. Create a DNS entry in route53 for production that consumers will use. The cloud formation creates one for prod-- but you do not want to use this as the CloudFormation can be deleted.

Lambda with no web API

Want a lambda that does not need a web API (that is invoked by something like sns)? Follow the steps above, but instead of using aws/cloudformation/cf-apig-single-lambda-resources.yaml for your resources CloudFormation, use aws/cloudformation/no-web-api-single-lambda-resources.yaml. You will use the same codebuild files and same CI/CD.

Astute developers may notice an APIG line in aws/codebuild/lambda-publish, however this has no impact and will not fail the build.

Backup info (if you care about inner workings)

The Lambda publishing process

The publishing process is multi-stage, with manual approvals, all handled in an automated fashion. Here are the details:

  • PublishTest step:
    1. Create Lambda if DNE. Set env vars from ssm namespace /test/[repo]/[branch]/[LAMBDA_NAME]/lambdaEnvs, role from /test/[repo]/[branch]/[LAMBDA_NAME]/lambdaExecutionRoleArn, timeout from /test/[repo]/[branch]/[LAMBDA_NAME]/lambdaTimeout, memory from /test/[repo]/[branch]/[LAMBDA_NAME]/lambdaMemory,
    2. Create Lambda version & alias test
  • When CodePipeline ApproveTest approved, PublishStaging step: :
    1. Update lambda. Set env vars from ssm namespace /staging/[repo]/[branch]/[LAMBDA_NAME]/lambdaEnvs, role from /prod/[repo]/[branch]/[LAMBDA_NAME]/lambdaExecutionRoleArn, timeout from /staging/[repo]/[branch]/[LAMBDA_NAME]/lambdaTimeout, memory from /test/[repo]/[branch]/[LAMBDA_NAME]/lambdaMemory.
    2. Copy zip package to s3://${S3_BUCKET_CONTAINING_PACKAGES}/${S3_PATH_TO_PACKAGES}/${codeSha256}.zip where codeSha256 is the just deployed staging lambda CodeSha256 configuration value. This ensures the code deployed to staging is the code that will be deployed to prod.
    3. Create Lambda version & alias staging
  • When CodePipeline ApproveStaging approved, PublishProd step: :
    1. Update lambda using ${codeSha256}.zip. Set env vars from ssm namespace /prod/[repo]/[branch]/[LAMBDA_NAME]/lambdaEnvs, role from /prod/[repo]/[branch]/[LAMBDA_NAME]/lambdaExecutionRoleArn, timeout from /staging/[repo]/[branch]/[LAMBDA_NAME]/lambdaTimeout, memory from /prod/[repo]/[branch]/[LAMBDA_NAME]/lambdaMemory.
    2. Create Lambda version & alias prod

About

aws-blueprint example for an API backed by single lambda

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages