Skip to content

Back end for Tacocat photo gallery implemented on Amazon AWS Serverless Application Model (SAM)

Notifications You must be signed in to change notification settings

deanmoses/tacocat-gallery-sam

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tacocat-gallery-sam

Back end for Tacocat's photo gallery. Implemented using the Amazon AWS Serverless Application Model (SAM).

Key services

Database (DynamoDB), image storage (S3), APIs (API Gateway), CDN (CloudFront), image EXIF/IPTC metadata extraction, image resizing.

Getting Started

Prerequisites

  • Node.js 18 or higher
  • The AWS Serverless Application Model Command Line Interface (SAM CLI)
  • esbuild installed globally (npm install --global esbuild)
  • I'm using the Visual Studio Code IDE with a lot of extensions, the AWS Toolkit is a key one

Install

  • Clone this project from github
  • Install dependencies: cd into its directory, cd app and then install dependencies with npm install or pnpm install or yarn. Note the app subdirectory! Due to the way SAM handles Typescript, the package.json and all the Node.js stuff is under app.

Build

Build the SAM app with the sam build command:

tacocat-gallery-sam$ sam build

This installs dependencies defined in app/package.json, compiles TypeScript with esbuild, creates a deployment package, and saves it in the .aws-sam/build folder.

It does NOT deploy to AWS; that comes later.

Unit & integration tests

Use NPM to install the Jest test framework and run unit tests...

tacocat-gallery-sam$ cd app
app$ npm install
app$ npm run test

... or better yet use Visual Studio Code's Jest support rather than dealing with the command line.

Invoke lambdas locally

Run Lambda functions locally via sam local invoke (this requires Docker) and passing it a test event:

tacocat-gallery-sam$ sam local invoke HelloWorldFunction --event app/src/test/data/events/some-event.json

An event is a JSON document that represents the input that the function receives from the event source. Some test events are in the app/src/test/data/events folder.

Debug lambdas locally

To debug a Lambda function locally, run the function in debug mode by adding -d 5858...

sam local invoke HelloWorldFunction -e app/src/test/data/events/events/some-event.json -n .env.json -d 5858

... then attach to the function in Visual Studio's debugger. You have to configure each Lambda individuall in .vscode/launch.json. Yes that's a hassle.

Run API locally

Use sam local start-api to run the API locally on port 3000:

tacocat-gallery-sam$ sam local start-api
tacocat-gallery-sam$ curl http://localhost:3000/

Deploy for the first time

To deploy your application to AWS for the first time:

sam build
sam deploy --guided

sam deploy --guided will package and deploy your application to AWS, with a series of prompts.

After the first time configures everything, use sam deploy or sam sync after that (see next section)

Deploy during development

While developing, run sam sync to keep watch over your lambda functions as they change and automatically deploy them to AWS. This skips the normal CloudFormation machinery and is thus much faster:

sam sync

Deploy to prod

To deploy to prod:

sam deploy --config-env prod

This will change the name of the stack to tacocat-gallery-auth-prod (look in samconfig.toml for how). Changing the name of the stack will create an entirely new stack with different resources.

Work with remote logs

The sam logs command fetches logs generated by your deployed Lambda functions.

Tail ALL Lambda functions in your AWS account:

sam logs --include-traces --tail

Tail a specific function:

sam logs --include-traces --tail -n HelloWorldFunction

Cleanup

To entirely delete the application from AWS:

sam delete

⚠️ ⚠️ This should delete the dev version. But since I've never tested it, this might delete the prod version with the S3 bucket with all the photos and the DynamoDB database, though I think it's set up not to delete them if they contain stuff.