The 10 commandments of serverless

Feedbacks on Serverless with AWS

Disclaimer: Despite the title, this is not a holy text. I discovered the serverless world in early 2016, when things were much more handicraft than today. Most of these lessons have been acquired by experiencing and failing. Read it, think about it and question it. Things are evolving quickly and some assumptions may be obsolete soon.

#1 You shall think microservices

I have always been a big fan of Lego bricks. This may be why I find myself so much in microservices. This analogy may help to understand all the stakes of this architecture.

Consider your microservices as Lego bricks

By building small but reliable components and assembling them to build complex things, you will gain on many angles:

  • Easier to maintain. As long as the interface between your services is well defined, you should be able to update a service without thinking too much about how it could impact other services.
  • Easier to handle technical debt. You will not be forced to do long and risky migrations to get rid of your legacy code or technologies. You can start using new practices in your services incrementally, by letting the old and the new way coexist for a while. You will then be able to validate the new methods as well as stabilizing them before applying them globally. It is like doing canary deployment but for your internal infrastructure.

#2 Avoid dependencies between services

This is not new to microservices, but dependencies have a much bigger impact. Having a microservices architecture with dependencies everywhere is an anti-pattern.

Be like Jon Snow
  • The way data are stored should only be known by the service itself, and no other service should assume a specific format. That way, you can completely change the inner mechanism overnight. It is one advantage I see using DynamoDB to store your data: your tables will belong to your service, will be deployed at the same time and you will implicitly segregate your data per service, instead of having a single database where any service can access any data.

#3 One language to rule them all

This is of course very subjective, but I believe JavaScript is the best language for the cloud, and here are the reasons:

  • Modern JavaScript has a really simple and clean syntax. async/await, among other things, revolutionized my daily life. Less code is better! If the last time you have used JavaScript was to do some jQuery in 2010, then you should have a look at this cheatsheet.
  • It has the biggest packages repository. You can focus on writing code that will benefit your business not reinventing the wheel.

#4 Organize your code in a monorepo

This debate will probably stay alive for a while, but:

  • It makes it easier to share code (at least for developing). There are various ways to share a library:
    - By publishing each package on npm. Lerna morepos may help getting some coherence. I personally think this makes a lot of sense for open source projects (see babel, turf), but versioning is constraining and not always necessary.
    - By encapsulating your shared logic in a service. I suggest you to read this article for more details.
    - By linking a folder locally (using `npm link`). It can have some side effects (more complicated webpack setup), but it is speeding up development time so much that I will probably stick with this option for a while.
  • It helps building a strong common CI. Microservices architecture makes functional and integration tests a key of your stability. I strongly encourage you to read this article that redefines the testing paradigm for serverless.

#5 Apply a naming convention

Of course the microservices architecture gives you some freedom on how each service behaves inside, but still as the number of your services will grow, you will need some consistency. I would suggest naming all your CloudFormation resources (even meaningless resources, like IAM roles) following a pattern, for instance {service-name}-{stage}-{resource-name}:

  • Having the stage in the name makes it possible to deploy the same service multiple times on the same account, so you can easily test features without breaking your environment.

#6 Serverless is not (only) FaaS

The fully managed combo Lambda/APIGateway/DynamoDB/S3 is obviously a really good starting point and should be enough for simple use cases. However you may quickly have longer or more complex processes:

  • How to reuse your basic functions across your services, and how to chain them within a process?
  • How to encapsulate non-serverless tasks (like a Batch job) in a serverless process?
A state machine execution on AWS Step Functions

#7 Equip yourself

I couldn’t recommend you a better framework than Serverless Framework:

  • It creates all your resources in CloudFormation stacks when using AWS.
  • You will find plugins to do almost everything.
  • The core is multi cloud providers (currently 8), which help standardizing the serverless architecture (FaaS services are quite similar is working almost the same way regardless of the provider).

#8 Adapt your tooling

Regardless of all its advantages, serverless is still early stage and this new paradigm also brings new problematics.

An example of transaction in Epsagon
The console

#9 Keep It Simple, Stupid (KISS principle)

Simple is sexy

#10 Make it easy to create a new environment

We can never say it enough, but automating everything in your deployments is the key. You should never create a resource outside of CloudFormation. It may take more time to develop, but you won't regret it. Here a a few reasons you may have to setup new environments:

  • Creating an environment per developer or per feature.
  • Expanding on other AWS regions.
  • What is part of your services and could be deployed many times in a single environment (to try a feature, or for a developer environment). As your resources contains the stage in their names it's now easy to make them coexist in the same AWS account.

#11 Have fun coding awesome things

Oh wait, is it already the 11th commandment? It doesn't matter, serverless is making your life such cooler that it becomes a duty to push the boundaries.

Serverless and JavaScript enthusiast