Versioning in AWS Lambda (Or, How to Not Break Your Lambda Code)

Have you gotten something working in AWS Lambda, but every time you want to make a change, everything breaks? Are you wondering how to separate code that’s in production versus what’s in development? You might’ve heard about versioning in AWS, but struggled with Amazon’s dense documentation. The point of this post is to explain the basics of versioning, quick and simple. There are two main concepts to learn: “versions” and “aliases”.

Versions

Lambda versions are like git commits— they’re snapshots of your project history. Each version has a number that serves as its ID, starting with 1 and incrementing up.

To make a new version, click “Actions”, then “Publish new version”. See below for an illustration:

This screenshot was harder to make than it looks

Note that you can only publish a version if you’re on the special version called “$LATEST”. This is the default version that all Lambda functions start on — it’s what you might be using without realizing it. This version $LATEST acts similar to git’s staging area — you make your changes there and when you publish a version, it takes whatever is in $LATEST and saves it as the new version — just like a git commit.

AWS never forces you to use versions, so it’s on you to publish new versions consistently. It’s again just like git commit — it’s on you to be diligent.

See below for an example of a Lambda version history:

You can see all the work I did to make a good fake lambda function

Aliases

Now that we’ve talked about versions, next up are aliases. Aliases are simply pointers to versions. As a metaphor, think of how you might have a pointer to different servers for development, staging, or production.

Similarly, we can use aliases to attach triggers. Triggers are the events that fire off your functions, such as file changes on S3 buckets or logs from CloudFront.

See below for an example of Lambda aliases:

My aliases are not-so-creatively named PROD and STG

Looking above, you’ll see this strange alias called “Unqualified”. It’s the default alias and it always points to the default version $LATEST. If you’ve never touched versions or aliases, you’d always be on Unqualified. If you never added any versions or aliases, then you’d always be making your changes to Unqualified, as well as attaching all your triggers to it. Think about that for a second: you’re making changes to the same code that’s being triggered. That’s dangerous — it’s like doing development on a production server. If you make a change that breaks anything, it’ll break for all services that rely on it.

There must be a better way. How about attaching our triggers to a version? In other words, we’ll publish a version that’s stable and attach our trigger to it. Any development we do will happen in Unqualified and when we’re ready, we can publish a new version and move our trigger to it. That’s much better.

However, moving triggers to a new version can be a pain — we have to delete the old trigger and attach a new one. Also, it’s hard to keep track of which version has which trigger. That’s where aliases come in. We can create an alias, attach our trigger to it, and have it point to a stable version. When we publish another version, all we need to do is change the pointer of the alias. Perfect!

Recap

Here’s a workflow that summarizes how to use versioning in Lambda:

0. Create an alias and attach your triggers to it
1. Do your development in “Unqualified” (the default state of Lambda)
2. When ready, publish a new version
3. Point the alias at the new version

Are you interested in working at a fast-growing startup? Aaptiv is hiring! Check out our jobs page.