AWS Lambda is a popular technique of Functions as a Service (or FaaS), part of the serverless trend. In this article, we introduce these concepts, illustrated with a demo project.

A Tour of AWS Lambda

(Mobile) Backend as a Service (or BaaS) is a way to connect (web and) mobile applications to various cloud services, from databases (like Firebase) to authentication layers (e.g., Auth0). Nonetheless, while BaaS is part of the serverless movement, we often only hear about Functions as a Service (FaaS), also known as lambda functions since Amazon called its implementation: Lambda. Both BaaS and FaaS are under the “serverless umbrella”, but what does serverless mean exactly?

Serverless

Do not get me wrong, the term “serverless” is just a name. Serverless does not mean we do not use servers anymore, but it rather expresses a slightly different way of managing servers. To the best of our knowledge, the notion of “serverless” describes the following ideas:

  1. Reducing/no maintenance: serverless is not about removing the servers but rather paying for services that mean that someone else manages the servers for you, hence reducing maintenance. It is about removing the need to manage uptime, upgrades, security vulnerabilities, and so on. As some people said already: “there is no serverless, it is just the cloud”;
  2. Less need for specific technologies: given that you do not have to maintain your own servers or own applications, you likely need less different technologies. This is especially important as it is the main difference with Platform as a Service (PaaS).
  3. Microservice-oriented: FaaS allows to expose different functionalities as units (functions). BaaS allows to use specific services from providers. In both cases, we end up with an application that becomes a set of interconnected and consistent components.

To sum up this part, serverless is a sort of abstraction layer for the servers, but it is neither a silver bullet nor the new Docker. There are always trade-offs when we rely on a third-party service, and this whole serverless thing implies numerous questions. For instance, what happens if the provider closes down? How complicated is it to switch from one provider to another? How do you deal with downtimes? How to debug an application whose (execution) environment is not accessible?

The hype around serverless is likely implied by FaaS, and emphasized by AWS Lambda, one way of running “code without provisioning or managing servers”, according to Amazon. The business model is to pay only for the compute time consumed.

Lambda

In the context of this article, a lambda or a lambda function is a regular function written in any programming language. It has input arguments, and most of the time, a lambda outputs some result. Such a function does not have much architectural restrictions, it is plain old code. Hence, providers like AWS Lambda accept lambda functions written in Python, JVM languages (Java, Scala, etc.) or Node.js. Given this capability, it is also possible to run other languages such as Golang. Check out Apex for instance! (Yes, we are aware of Serverless Framework too :wink:)

There is one distinguishing feature though: lambda functions are stateless. No one really knows where the function is executed, and two consecutive calls to a same lambda do not share any state tied to the runtime. Question is: who stores the state? Because there must be a state at some point! One option is to rely on a database to store the state across the different calls.

Last but not least, one of the main differences with traditional systems is the deployment phase: the source code of the lambda function is uploaded to the provider, which then handles everything else: from executing the function to scaling it (horizontally) if needed.

To sum up, a lambda is a function that does one thing well (hopefully) when triggered by an event along with input parameters, and eventually outputs a result. This is what we call an event-driven system. AWS Lambda proposes different events to trigger lambdas, such as changes to data in an Amazon S3 bucket or an Amazon DynamoDB table. It is also possible to use an API Gateway to expose a lambda function, and this is the purpose of the next section.

API Gateway

As stated previously, a lambda must be triggered by some sort of call. One of the most common methods for web-based applications is to rely on an API Gateway, which is an HTTP server where routes are defined in configuration and associated with a lambda. When a gateway receives a request, it calls the corresponding lambda. First, the HTTP request parameters are mapped to input arguments of that lambda. Then, the result of the lambda invocation is transformed into an HTTP response and sent back to the client thanks to the gateway.

Amazon API Gateway is an example of an API Gateway, which integrates well with AWS Lambda. The AWS environment allows to connect lambdas to many other services, but also third-party components, e.g., to add an authentication layer using Auth0.

Demo

To illustrate this article, we open sourced a demo project providing a Python AWS Lambda exposed with AWS API Gateway, and configured with Terraform. You can grab the code at:

This demo creates an API thanks to AWS Gateway. This API contains a unique /hello endpoint along with two methods (GET and POST). Both methods are bound to a single lambda containing two handlers (one function per HTTP method). It seems quite unusual according to the other tutorials but this is our way of organizing our lambda functions into consistent chunks. These functions are written in Python:

def handler(event, context):
    return { "message": "Hello, World!" }

def post_handler(event, context):
    return { "message": "I should have created something..." }

The whole infrastructure is managed with Terraform, which is “a tool for building, changing, and versioning infrastructure safely and efficiently”. We created two Terraform modules (lambda and api_method) for this demo project, and both are reusable in your own projects!

For example, the lambda module is strongly opinionated. It requires to use the same name for the source file, the lambda (in AWS), and the zip files. Other parameters like runtime, role, and the handler are configurable:

module "lambda" {
  source  = "github.com/TailorDev/hello-lambda/lambda"
  name    = "my-lambda"
  handler = "handler"
  runtime = "python2.7" # could be nodejs | nodejs4.3 | java8 | python2.7
  role    = "my-role"
}

The second module, named api_method is the one responsible for binding a lambda function to a specific HTTP method. The file hello_lambda.tf contains the configuration (with comments) for this demo project.

The figure below is a screenshot of the AWS API Gateway dashboard obtained after having run terraform apply. This is idempotent, so you can run terraform destroy && terraform apply forever :heart:

Important: you must have an AWS account to run this project. It is eligible to the AWS Free Tier in case you want to give it a real try, but be careful: it might cost money at some point.

One more thing

This article about serverless is not exhaustive, that is why you will find a few more links below, in case you are interested in learning more, especially on the “NoOps” thing:


By the way, if you are running lambdas or you are Terraform fans, we would love to hear about your own techniques for managing your infrastructure. Drop us a note by email (hello@tailordev.fr) or on Twitter!