Back

Building my first Lambda, and the $LATEST mistake

I built a small serverless app on AWS: Lambda, API Gateway, DynamoDB, and a static S3 page in front. These are my notes on the choices I made and the one mistake worth writing down.

The setup

API Gateway takes the request and invokes the Lambda. The Lambda runs the logic and reads and writes DynamoDB. S3 serves the frontend. I chose this because there is no server to patch, and nothing runs or costs money when there is no traffic. For an app this small that was the right choice.

Packaging

You can ship a Lambda as a zip of your code or as a container image. I used a zip. It is simpler, and there is no reason to use a container until your dependencies get large (the zip path caps at 250 MB unzipped) or you need a custom runtime. My handler was small, so a zip was fine. A container would have added an ECR repository and cold-start tuning for no benefit at this size.

The mistake: pointing at $LATEST

I connected API Gateway directly to $LATEST. It worked, so I left it.

When I later pushed a bug fix, the endpoint I had been testing changed behavior, and I could not tell which version of the code had served a given request. $LATEST is overwritten in place on every deploy, so there is no fixed record of what ran. It took me a while to work out that the problem was not my code but the fact that I had nothing pinned.

What I changed:

  1. On every deploy I publish a version. A version is a frozen snapshot of the code and config that does not change once created.
  2. I put an alias in front and point API Gateway at the alias, not at $LATEST. Moving to new code now means moving the alias on purpose, not something that happens silently.

There is a heavier setup I read about and did not need yet: a weighted alias that sends a small percentage of traffic to the new version first, with CodeDeploy shifting the rest gradually and rolling back automatically if a CloudWatch alarm fires. That is worth it for a real production endpoint. For this app, a published version behind an alias was enough.

What I would do differently

  • Keep the handler small so zipping stays simple and cold starts stay low.
  • Publish a version and put an alias in front from the first deploy. Adding this after you have traffic is more work than starting with it.
  • Do not leave anything pointed at $LATEST once the output matters.

It is a small app, but it runs and I understand every part of it, which was the point.


References