The Serverless 12-Factor App
What is a 12-factor app?
Adam Wiggins, the co-founder of Heroku, first popularized the concept in 2011, and the source of truth for the whole manifesto is 12factor.net. I say “manifesto” because it reads something like the Agile Manifesto. It’s a series of principles that, as you approach them, may make your software-as-a-service applications better.
It’s appropriate that this came out of Heroku because one of the ways it’s supposed to make your apps more ready to deploy on cloud platforms.
These tenets also optimize:
- Dev and staging environments- There’s less difference between the two.
- Deployments- They become easier and therefore do continuous delivery better.
- Setup- It’s easier to understand, which should make onboarding more intuative.
To give an example number four is “Treat backing services as attached resources” and you can go read on 12factor.net exactly what they mean. I think it’s possible to disagree how important all these goals are, but it’s hard to argue that solid encapsulation, declaration and management won’t make your apps more portable and easier to scale
Why does this matter for Serverless?
With containers, we move into a world where the platform or service provider is managing a lot of problems on your behalf. The idea is that this gets us closer to that ever-elusive goal of spending less time heavy-lifting technical problems and more time focusing on business needs.
So great! Serverless means you worry about less arbitrary ops stuff and everyone will see benefits if they adopt it. But I’ve heard at least two managers saying “yeah we’d like to adopt serverless but it presents so many headaches for developers. I don’t wanna burden my team with that.”
Now I could respond by saying that if serverless is making their dev process harder, the team is doing it wrong. But that kind of buries the lede. To me, the real takeaway is that, as cool and automated as individual services on AWS are, it’s possible that using multiple services with multiple developers turn it into a nightmare to build on.
By following some of the 12 factors we can get closer to something that’s a joy for your team to use.
Wait only some of the 12 factors apply?
Correct. Not all of them apply to serverless. I first read 12factor.net after reading Chris Munns’ material about it. He writes “for serverless, it’s a seven-and-a-half factor app.”
For example, number six is “Execute the app as one or more stateless processes.” While that’s not a bad thing to do with serverless, it’s also entirely handled for you.
So five or so of these principles are things that happen automatically with serverless and it’s impossible to mess up, so they don’t really merit talking about. It “half” applies because the concept of disposability is kind of relevant.
Which 5 don’t really apply to Serverless?
Execute the app as one or more stateless processes
Export services via port binding
Scale-out via the process model
Maximize robustness with fast startup and graceful shutdown
Run admin/management tasks as one-off processes
Tools that enable good practices
Some of the requirements from 12factor.net are easy enough to do with good practice. Like number two: “Explicitly declare and isolate dependencies.” Yes, for your node Lambda you should maintain an accurate package.json. No special tooling required!
Others require you to get familiar with some other tools like CloudFormation and Secrets Manager to really follow the advice on managing configuration.
But there are still some key features that aren’t really available natively in the AWS console. Just as one example, there’s not really a way to have an environment in AWS, there’s no way to say “deploy this new Lambda code to our staging environment.”
While you can use CloudFormation to create a bundle of environment variables for your Lambdas, there’s no one-click way to switch out a bundle of settings and config for the production versions. Worse, if you want to say change a table name for everything running on staging there’s no way to do that either. At all!
But good news! Stackery’s ‘Environments’ tooling can do just that. Stackery also treats your serverless application as a whole that is much more than just Lambdas, and its canvas connects those components with just a few clicks.
So what are the biggest lessons from this series?
You have to read the whole series for that! It’s already got so much in it and I’m only halfway through!
Seriously though, in general, the things you need to add to your serverless apps comes in three sections:
- Manage your dependencies
- Think of your app not as “just functions” but also the required services backing it.
- Abstract your configuration for each environment
I recently talked about this on The New Stack’s Context podcast, so check that out if you want to hear my dulcet tones.
The source text for all this is 12factor.net; and again, I was inspired by Chris Munns writing about 12-factor and Serverless. My full series writing up each principle as they apply to serverless is on The New Stack.