Serverless Framework: A Deep Overview of the Best AWS Lambda + API Gateway Automation Solution

Architecting AWS-Powered Microservices in Python with Serverless Framework: What You Need to Know

We have been talking a lot about the new serverless cloud over the last few months. The news is all good. There have been tremendous improvements announced since AWS Lambda’s launch in 2014.  Competing cloud vendors are working hard to catch up with AWS when it comes to serverless infrastructure-as-a-service.

Developing in a serverless fashion will definitely improve the life of developers and DevOps professionals — although we are still in the early days of this revolution.

Smart developers quickly realized the need for automation and structure, especially when orchestrating a nontrivial system of APIs and microservices.

In this post, we’re going to cover the following topics:

  • The history of Serverless Framework.
  • The basics of architecting applications in Serverless Framework.
  • The Serverless Framework command-line interface (CLI).
  • How to develop Serverless Framework applications in Python.

The Serverless Framework: A Brief History

Serverless Framework Logo
With the goal of making the serverless transition smoother for everyone, the AWS community started working on a complete solution to develop AWS-powered microservices or backends for web, mobile, and IoT applications. The migration required facilitation because of the building-block nature of AWS Lambda and its complex symbiosis with Amazon API Gateway.
That’s how the Serverless Framework was born (formerly JAWS). Thanks to the hard work of @austencollins, JAWS made it to the HN homepage last Summer and was successfully presented at re:Invent 2015 in Las Vegas, Nevada thereafter.

To date, the project counts more than 60 contributors on GitHub and boasts an active ecosystem of plugins and tutorials. Take a look at an awesome curated list of resources related to the Serverless project.

ServerlessConf and the Serverless Community

The future will be Serverless. [@ServerlessConf]

The Serverless community is constantly growing, and not only within the AWS ecosystem. It is robustly supported by active meetups in San Francisco, New York, Melbourne, and Sydney.

If you feel like witnessing history in NYC, keep an eye on the (sold out) ServerlessConf this week. I will personally attend the event, and I’ll be glad to meet you there.

It will be fun to attend, but don’t panic if you didn’t secure a ticket. All the videos will be available online after the event.
ServerlessConf

Serverless Framework: The Basics

The Serverless Framework forces structure into serverless code by providing a minimal and clear organization for your lambda functions. The advantage of this structure means you will benefit from all the AWS best practices that were painstakingly built into in the framework. This structure effectively frees developers from low-level details about versions, aliases, stages, variables, roles, etc.

Rising above these details leaves room for greater productivity (and maybe a longer lunch).

As a software engineer, this freedom from drudgery allows you to focus on the business logic — which is the main goal of AWS Lambda itself.

On the operations side, the framework will also take care of the deployment process, which can easily become the most annoying part of using AWS Lambda – especially if your use case is complex.

Typically, you would need to bind together Lambda functions and API Gateway endpoints, configure the request/response integrations, deal with multiple stages and aliases (i.e. dev, prod, etc.), build, and upload your deployment package.
Once you successfully complete these steps, you’ll likely be required to do it again in more than one AWS region.

Installation and Code Organization

The Serverless Framework is built in JavaScript and requires Node V4. You can install it via npm:

npm install serverless -g

Once the package is installed globally, you can create or download a new project and start working on your Lambda functions in JavaScript (Node.js 0.10 or 4.3) or Python 2.7.

Most of the time, your Lambda functions will require some external dependencies. Keep in mind that you will need to upload these libraries together with your own code.

Finally, the compiled code must be compatible with the operating system used by AWS Lambda under the hood (e.g. CentOS).
The Serverless Framework suggests developers organize their code as follows:

  • Group your functions into subfolders
    (i.e. “/functions/myfunction1/“, “/functions/myfunction2/“, etc.)
  • Define a module to share common code among your functions
    (i.e. “/functions/lib/“), this way you will separate the Lambda boilerplate from your core logic
  • Define your dependencies as a package.json or requirements.txt file, eventually for each function, so that you install them via npm or pip: the framework will take care of zipping and uploading your node modules or Python Virtualenv.

Please note that the framework is still in Beta release (currently v0.5.5) and future versions might contain breaking changes due to the quickly evolving serverless landscape. That said, I am confident that most of the above mentioned best practices are fairly stable, as are the following ones.

Serverless Framework CLI and Concepts Overview

The framework exposes an interactive CLI that lets you manage and automate every phase of your workflow. You’ll need to become comfortable with the following critical concepts:

  • Projects: you can configure independent serverless projects, either by starting from scratch or from ready-to-use, installable and shareable projects (available as npm packages).
  • Plugins: the framework comes with a rich set of plugins that add useful functionalities to the core, such as CORS support, code optimization, and linting, Cloudwatch + SNS logging, TDD, and others. Feel free to create and publish your own plugins to better structure and share your code. There is also an official plugins registry.
  • Stages: each stage represents an isolated environment, such as dev or prod. You can use them to separate and isolate your AWS resources. As a best practice, the framework lets you start with a default dev stage.
  • Regions: these are an exact mapping of the official AWS regions. You may want to deploy each stage into a different region to achieve total separation, or even distribute your resource across multiple regions to optimize your system performance.
  • AWS Profiles: each profile corresponds to a valid combination of your AWS account access keys. You may want to use a different profile for each stage and eventually use totally different AWS accounts.
  • Functions: functions are the real core of your project, and the Serverless framework lets you organize them as you like, even if some sort of structure is highly recommended (really). Each function will ultimately correspond to a folder in your file system, with its own code (only JavaScript or Python, for now), its configuration, and a test event.
  • Endpoints: each function can potentially be bound to multiple endpoints, which correspond to API Gateway resources and methods (i.e. HTTP endpoints). You’ll need to declare them in each function configuration.
  • Events: if you need to invoke your function upon particular events – or in a recurring basis – you can declare a set of events in its configuration file (e.g. dynamodbstream, kinesisstream, s3, sns or schedule).
  • Resources: for each stage and region, you can define a set of CloudFormation resources, such as IAM roles, policies, etc. Interestingly, you can easily show the diff between your local configuration and the deployed resources.
  • Templates & Variables: these are a useful tool to reduce the size and redundancy of your configuration files. Variables can hold only numbers and strings, while templates allow you to define complex structures, in a hierarchical fashion.
  • Dashboard: the framework provides an interactive deployment dashboard, to visualize and select which resources to be deployed concurrently. You can also be shown a graphical summary of the current status of your project (see screenshot below).
Serverless Framework CLI

A Real-World Serverless Example in Python

The Serverless Framework comes with a very useful boilerplate project for JavaScript functions. It will give you a great overview of how to organize your projects and provide a stable base to bootstrap a new one.

I personally took the time to create a new starter project for Python functions.

You can quickly download and install it by executing the following command:

serverless project install serverless-starter-python

This project, in particular, doesn’t come with any dependencies, but normally you’d need to install them via npm:

cd serverless-starter-python
npm install

Then, you will need to install your Python dependencies in a specific folder, as follows:

cd restApi
pip install -t vendored/ -r requirements.txt

Note: the “restApi” folder contains all our functions in this project. Eventually, you can have more than one root-level folders, and even sub-folders (see “restApi/multi/show” and “restApi/multi/create“).

But let’s focus on “restApi/continent“: this Lambda function takes a country name as input (e.g. “Germany“) and will return the corresponding continent (e.g. “Europe“). In order to demonstrate how to use Python dependencies, I implemented the function by using the countrycode module (see requirements.txt).

As a best practice, I organized the Lambda function code as follows:

  • restApi/continent/handler.py” only contains the basic handler logic, plus some sys.path magic to include the common library.
  • restApi/lib/continent.py” defines a continent_by_country_name function, which implements the actual business logic.
  • restApi/lib/__init__.py” takes care of exposing the library utilities and including our Python dependencies in the sys.path (the “vendored” folder where we installed our requirements).

Here is the main function logic:

from countrycode import countrycode
def _error(msg):
    """ Utility to handle custom errors (see response mapping) """
    raise Exception("[BadRequest] %s" % msg)
def continent_by_country_name(event):
    """ Get continent name (e.g. "Europe"), given a country name (e.g. "Italy") """
    country_name = event.get('country')
    if not country_name:
        return _error("Invalid event (required country)")
    continent = countrycode(codes=[country_name], origin="country_name", target='continent')
    if not continent:
        return _error("Invalid country: %s" % country_name)
    return {
        "continent": next(iter(continent)),
    }

In order to demonstrate how to handle errors, I have wrapped the required logic in a _error function: it will simply raise a Python Exception with a well-defined structure. Indeed, here is how I defined the corresponding endpoint responses:

{
  "name": "continent",
  "runtime": "python2.7",
  "handler": "continent/handler.handler",
  ...
  "endpoints": [
    {
      "path": "continent",
      "method": "GET",
      "requestTemplates": "$${apiRequestTemplate}",
      "responses": {
        "400": {
          "selectionPattern": "^\\[BadRequest\\].*",
          "responseModels": "$${apiResponseModelsError}",
          "responseTemplates": "$${apiResponseTemplateError}",
          "statusCode": "400"
        },
        ...
      }
    }
  ]
}

As you can see in the “selectionPattern” definition, API Gateway will match any “[BadRequest]” prefix whenever you raise a Python Exception and bind it to a 400 – Bad Request HTTP response. Here you can see Templates in action: you can define and re-use them everywhere with the $${NAME} syntax.

Furthermore, I customized how the HTTP response is sent back in case of 400 errors, in our “restApi/continent/s-templates.json”:

{
  "apiRequestTemplate": {
    "application/json": {
      "country": "$input.params('country')"
    }
  },
  "apiResponseModelsError": {
    "application/json": "Error"
  },
  "apiResponseTemplateError": {
    "application/json": {
      "message": "$input.path('$.errorMessage')"
    }
  }
}

Here I defined three templates:

  • apiRequestTemplate is used to map the querystring “country” parameter into an explicit event parameter;
  • apiResponseModelsError associates API Gateway’s default Error model to our 400 response, which contains only a “message” parameter;
  • apiResponseTemplateError defines how to build our 400 HTTP Response body and is particularly useful if you want to hide the default stack trace and map “errorMessage” into the model’s “message” parameter.

Let’s test our function locally.

I have defined a local test event in “restApi/continent/event.json“, which contains a simple JSON structure such as {“country”: “Germany”}. You can easily run your function with the following command:

serverless function run continent

If everything went right, the framework will print out something like {“continent”:”Europe”}.

Once you are happy with your functions, you can launch the (beautiful) deployment dashboard:

serverless dash deploy

This dashboard is designed to be interactive. Here you can choose which resources you want to deploy, with a very intuitive interface. As I mentioned earlier, the framework will take care of all the details. It will create new Lambda versions, associate them with the right alias, re-deploy API Gateway stages, update every template mapping, etc.

Here is what the interactive dashboard looks like:
Serverless Framework Deployment
Once you confirm the operation, everything will be checked and deployed smoothly. You will also be given the HTTP endpoints for each updated Endpoint.

Of course, you can also decide to remove your functions and endpoints with a single command:

serverless function remove continent

Keep in mind that the framework will only delete the AWS Lambda aliases and the API Gateway resources associated to the corresponding stage. It means that all your functions versions will be still available on AWS, should you need them later on. This is possible because the framework never uses your Lambda functions’ $LATEST version, which is highly discouraged in general unless you are just prototyping.

More Serverless Resources

I personally believe the Serverless Framework – even if still in Beta – is a complete and robust solution for organizing complex projects. I expect these frameworks will continue improving and continue impressing users with new and more powerful features.

I would like to mention a few more serverless frameworks worth investigating:

  • Zappa: facilitates the deployment of all Python WSGI applications on AWS Lambda + API Gateway.
  • Kappa: a command line tool that (hopefully) makes it easier to deploy, update, and test functions for AWS Lambda.
  • Apex: lets you build, deploy, and manage AWS Lambda functions with ease (with Golang support!).
  • Lambda-complex: a Node.js framework for applications that run entirely within Lambda, SQS, and other high abstraction layers AWS services.
  • λ Gordon: an automation tool based on self-contained CloudFormation templates (Python, Javascript, Java, Golang and Scala support).

Do You Always Need a Full-Fledged Framework?

Sometimes, you want to keep complexity and friction as low as possible, especially for small projects or experiments. In these cases, you may prefer simpler solutions that better integrate with your existing code and solve only a single problem. Here is a small collection of such projects:

  • λambdify: a tool that turns any python callable into an AWS Lambda function.
  • Python-lambda: a toolset for developing and deploying serverless Python code in AWS Lambda.
  • Cloudia.js: it helps you easily deploy Node.js microservices to Amazon Web Services.

Here’s How You Can Easily Learn the Fundamentals of Serverless Design

There are plenty of resources for learning serverless. Here are some of the best:

The Serverless Cloud

It turns out serverless computing is also popular outside of the AWS ecosystem. Every cloud vendor is building its own serverless solution.

Why? Apparently, because developers really like this new level of abstraction. Roughly speaking, not dealing with operations and server maintenance simply sounds better, even without considering the powerful event-oriented approach offered by the serverless architecture.
Even though serverless computing doesn’t completely remove operations from your workflow, I personally believe it makes developers more comfortable, and drastically increases the ownership of their code.
Here are some of the main AWS Lambda alternatives, even if most of them are still alpha versions or not as complete as they should be:

  • Google Cloud Functions: here is my review of Google’s serverless solution (still in limited preview); it currently supports only JavaScript.
  • Microsoft Azure FunctionsAzure’s solution – still in preview – looks very promising, but I haven’t had a chance to try it yet. It supports a wide variety of languages, including JavaScript, C#, Python, PHP, Bash, Batch, and PowerShell.
  • IBM Bluemix OpenWhisk: also IBM’s solution is still in alpha and I might give it a try soon. It currently supports JavaScript and Swift.
  • Iron.io: it is a serverless platform built on top of Docker and Golang. This one is language agnostic and currently supports Golang, Python, Ruby, PHP, and .NET.

I am still looking forward to a future where a great codebase like the Serverless Framework is vendor neutral and allows developers to work on the Cloud platform of their choice.

Let us know what you like or dislike about serverless computing, especially if you are using the Serverless Framework.

Avatar

Written by

Alex Casalboni

Alex is a Software Engineer with a great passion for music and web technologies. He's experienced in web development and software design, with a particular focus on frontend and UX.


Related Posts

Patrick Navarro
Patrick Navarro
— January 22, 2020

Top 5 AWS Salary Report Findings

At the speed the cloud tech space is developing, it can be hard to keep track of everything that’s happening within the AWS ecosystem. Advances in technology prompt smarter functionality and innovative new products, which in turn give rise to new job roles that have a ripple effect on t...

Read more
  • AWS
  • salary
Alisha Reyes
Alisha Reyes
— January 6, 2020

New on Cloud Academy: Red Hat, Agile, OWASP Labs, Amazon SageMaker Lab, Linux Command Line Lab, SQL, Git Labs, Scrum Master, Azure Architects Lab, and Much More

Happy New Year! We hope you're ready to kick your training in overdrive in 2020 because we have a ton of new content for you. Not only do we have a bunch of new courses, hands-on labs, and lab challenges on AWS, Azure, and Google Cloud, but we also have three new courses on Red Hat, th...

Read more
  • agile
  • AWS
  • Azure
  • Google Cloud Platform
  • Linux
  • OWASP
  • programming
  • red hat
  • scrum
Alisha Reyes
Alisha Reyes
— December 24, 2019

Cloud Academy’s Blog Digest: Azure Best Practices, 6 Reasons You Should Get AWS Certified, Google Cloud Certification Prep, and more

Happy Holidays from Cloud Academy We hope you have a wonderful holiday season filled with family, friends, and plenty of food. Here at Cloud Academy, we are thankful for our amazing customer like you.  Since this time of year can be stressful, we’re sharing a few of our latest article...

Read more
  • AWS
  • azure best practices
  • blog digest
  • Cloud Academy
  • Google Cloud
Avatar
Guy Hummel
— December 12, 2019

Google Cloud Platform Certification: Preparation and Prerequisites

Google Cloud Platform (GCP) has evolved from being a niche player to a serious competitor to Amazon Web Services and Microsoft Azure. In 2019, research firm Gartner placed Google in the Leaders quadrant in its Magic Quadrant for Cloud Infrastructure as a Service for the second consecuti...

Read more
  • AWS
  • Azure
  • Google Cloud Platform
Alisha Reyes
Alisha Reyes
— December 10, 2019

New Lab Challenges: Push Your Skills to the Next Level

Build hands-on experience using real accounts on AWS, Azure, Google Cloud Platform, and more Meaningful cloud skills require more than book knowledge. Hands-on experience is required to translate knowledge into real-world results. We see this time and time again in studies about how pe...

Read more
  • AWS
  • Azure
  • Google Cloud
  • hands-on
  • labs
Alisha Reyes
Alisha Reyes
— December 5, 2019

New on Cloud Academy: AWS Solution Architect Lab Challenge, Azure Hands-on Labs, Foundation Certificate in Cyber Security, and Much More

Now that Thanksgiving is over and the craziness of Black Friday has died down, it's now time for the busiest season of the year. Whether you're a last-minute shopper or you already have your shopping done, the holidays bring so much more excitement than any other time of year. Since our...

Read more
  • AWS
  • AWS solution architect
  • AZ-203
  • Azure
  • cyber security
  • FCCS
  • Foundation Certificate in Cyber Security
  • Google Cloud Platform
  • Kubernetes
Avatar
Cloud Academy Team
— December 4, 2019

Understanding Enterprise Cloud Migration

What is enterprise cloud migration? Cloud migration is about moving your data, applications, and even infrastructure from your on-premises computers or infrastructure to a virtual pool of on-demand, shared resources that offer compute, storage, and network services at scale. Why d...

Read more
  • AWS
  • Azure
  • Data Migration
Wendy Dessler
Wendy Dessler
— November 27, 2019

6 Reasons Why You Should Get an AWS Certification This Year

In the past decade, the rise of cloud computing has been undeniable. Businesses of all sizes are moving their infrastructure and applications to the cloud. This is partly because the cloud allows businesses and their employees to access important information from just about anywhere. ...

Read more
  • AWS
  • Certifications
  • certified
Avatar
Andrea Colangelo
— November 26, 2019

AWS Regions and Availability Zones: The Simplest Explanation You Will Ever Find Around

The basics of AWS Regions and Availability Zones We’re going to treat this article as a sort of AWS 101 — it’ll be a quick primer on AWS Regions and Availability Zones that will be useful for understanding the basics of how AWS infrastructure is organized. We’ll define each section,...

Read more
  • AWS
Avatar
Dzenan Dzevlan
— November 20, 2019

Application Load Balancer vs. Classic Load Balancer

What is an Elastic Load Balancer? This post covers basics of what an Elastic Load Balancer is, and two of its examples: Application Load Balancers and Classic Load Balancers. For additional information — including a comparison that explains Network Load Balancers — check out our post o...

Read more
  • ALB
  • Application Load Balancer
  • AWS
  • Elastic Load Balancer
  • ELB
Albert Qian
Albert Qian
— November 13, 2019

Advantages and Disadvantages of Microservices Architecture

What are microservices? Let's start our discussion by setting a foundation of what microservices are. Microservices are a way of breaking large software projects into loosely coupled modules, which communicate with each other through simple Application Programming Interfaces (APIs). ...

Read more
  • AWS
  • Docker
  • Kubernetes
  • Microservices
Nisar Ahmad
Nisar Ahmad
— November 12, 2019

Kubernetes Services: AWS vs. Azure vs. Google Cloud

Kubernetes is a popular open-source container orchestration platform that allows us to deploy and manage multi-container applications at scale. Businesses are rapidly adopting this revolutionary technology to modernize their applications. Cloud service providers — such as Amazon Web Ser...

Read more
  • AWS
  • Azure
  • Google Cloud
  • Kubernetes