Serverless architecture is something Phase2 has been using for services and tasks, such as external content ingestion, data transformation and normalization, and providing access to external datasets for web applications. One aspect of serverless is Function as a Service (FaaS), which has opened the door to some new and intriguing approaches to application architecture. The idea of managing functional services without the need to worry about managing infrastructure or server resources is captivating, to say the least. The speed at which a developer can build from prototype to production also holds a fair amount of appeal.
So what exactly does “serverless” mean? Don’t you still need a server to run your function’s code?
Manage the Application, Not the Server
Serverless is a type of cloud computing that uses runtimes rather than a dedicated cloud environment. A cloud hosting provider handles all of the infrastructure’s resource management. When a function is invoked externally, a runtime engine executes the function’s code, and then the runtime spins down and disappears. Conceptually, this means there is no active server running while code is sitting idle. This also means that there is no machine state between code executions.
Serverless doesn’t mean there is no hardware involved; rather, it simply means that an application developer is not involved in the management of the hosting infrastructure, nor anyone in that developer’s IT department or elsewhere in their organization. Instead, all server-related duties devolve to a Backend as a Service (BaaS) provider, such as Amazon AWS, Microsoft Azure, or Google Cloud Functions (to name a few).
This allows a developer to focus solely on the development of their application. A serverless developer will spend significantly less time worrying about things like scale, since all resources are managed dynamically and on-demand. Function execution is event-driven and instantaneously scalable without any setup or effort on the developer’s end.
There is also rarely the need to consider cost, since FaaS providers only charge for runtime execution and not for time while the application’s function is idle. Billing is based on consumption and runtime executions, not server instance sizes or resources.
A developer may consider several use cases that are a good fit for FaaS. Some high-level cases might be:
- Scheduled tasks or jobs
- Processing a web request
- Processing queue messages
- Manually executed tasks
- Collecting, transforming, and saving collections of data
More specific examples might be:
- Backend to Web Applications / Single Page Applications / Frontend Application
- Mobile / IoT Backends
- Data Integration / Processing services
- Event or message based microservices
- Continuous content migration or incremental data imports
Getting Started with FaaS
There are two primary steps needed before any developer can begin writing serverless code:
- Choose a BaaS provider
- Select a serverless framework (optional, but highly recommended).
The big three cloud providers that have mature serverless options are Amazon, Microsoft, and Google. There are some others that are gaining steam as well. While all of these are proprietary paid services, each offers a significantly useful free tier. These free tiers offer enough computer time, resources, and access to additional services to allow for significant prototyping and testing.
Amazon AWS Lambda was the first (successful) provider for FaaS. Creating an initial account, and subsequent IAM users is free. Getting started with Lambda functions is well documented, and Amazon recommends using docker-lambda for local development. Lamda initially only offered Node.js, but has since extended to other languages such as Python, Java, C# (.NET Core), and Go. The free tier offers 1 million requests per month, but the free account may expire after 12 months.
Amazon offers countless services and features, and almost all of these have interoperability with Lambda. Many of these services can be used as events and triggers for a Lamba function, including API gateway request, S3 file events, SQS messages, Alexa skill invocations, and DynamoDB updates, to name a few.
Microsoft Azure also offers a free tier, along with with access to several dozen other Microsoft Cloud services. Azure supports Node.js, PHP, Java, C#, and F#. The free account includes a credit towards some services, 12 month limit on other free services, and a few dozen other always-free services. They also offer 750 hours of compute time on Linux and Windows VMs, as well as database and disk storage as part of their free account.
In recent years, Microsoft has been making a big splash in the Open-Source Software community, including significant contributions to git as well as its recently announced acquisition of Github. This, combined with it’s extensive history of product development has lead to Microsoft offering some of the most polished FaaS services to date, including a quick and easy to follow guide to getting started with Azure, which includes a video demo that promises a deployed function within 10 minutes.
Azure functions can be triggered through a variety of Microsoft’s other services, including HTTP and Webhooks, Blob storage CRUD, Event Hub stream events, Cosmo DB changes, Microsoft Graph (Auth, Excel, OneDrive, Outlook, etc.), Twilio Voice, SMS, Video events, and External File (Dropbox, Drive, etc.) folder changes.
Google Cloud Functions also has a free tier, and a slightly more complicated getting started guide. However, the free tier is also the simplest to manage, and offers up to 2 million invocations per month and 1 million seconds of free compute time during that same month. It also offers the Google Cloud SDK and gcloud components for local development work. However, Google Cloud Functions only offers Node.js 6 at this time.
Google Functions can be triggered by Cloud Endpoint HTTP invocations, storage events, and Cloud Pub/Sub event streams. Google also has Firebase, which is a mobile oriented BaaS. This can also trigger Cloud Functions with Firebase database events, Storage events, Auth events, and Analytics events.
There are a number of other FaaS players to consider.
IBM has their own PaaS called Bluemix, which offers a FaaS service called OpenWhisk. It has been created as an Apache project, and is open sourced. It supports a large set of languages, including Java, Node.js, Go, PHP, Swift, Python, Ruby Sinatra, Ruby on Rails, and other languages can be extended through buildpacks.
Fission.io is a Kubernetes based FaaS provider, which works well with Dockerized containers and local development.
CloudFlare Workers is part of the CloudFlare CDN suite, and offers FaaS at the Edge. This makes FaaS possible to use as an edge-side include fragment, among other things. It makes for some interesting customizations and personalization, and can be used for authentication on otherwise highly-cached web sites.
Kubeless is an open-source project that offers a serverless framework using Kubernetes for auto-scale and routing. Kubeless events can be triggered easily with HTTP or PubSub.
Following their quick start guides and documentation, a developer who is new to serverless and FaaS can get their first prototype up quickly. However, when developing in the context of a larger, more complex application or system, having discreet functions everywhere can easily become difficult to manage. To simplify things, there are several serverless frameworks that developers can use.
By far, the easiest framework to use is, aptly named, Serverless. Serverless is a toolkit that installs locally (or within a Docker container), and sets up a collection of Node commands and templates via NPM; and in less than a handful of "serverless" Node commands, any developer can deploy a function to any provider within minutes. Using the Serverless framework means a developer doesn’t need to use a web interface to manage individual functions, and instead, can use a set of helper CLI tools to help manage their collective application.
The Serverless framework manages user credentials and templates for all the major providers, so developers have to worry even less about infrastructure-specific considerations. It can also be extended using plugins. Using Serverless is highly recommended to get started.
Another framework to consider is Up, which is in many ways the successor to Apex. It is an AWS specific framework, built for easily deploying apps and websites. It has HTTPS built in, and a number of pro services, such as variable encryption and the removal of cold starts.
By default, Up supports Node.js, Golang, Python, Java, Crystal, and static HTML sites. Some of these languages are not natively supported by Lambda; Up provides additional elements to extend language support. For instance, Up takes advantage of Lamba’s native Java support to allow for any JVM based languages (hence, Clojure).
What to Consider When Considering FaaS
Serverless functions are triggered by events, and are often subject to execution duration limits and startup latency. Latency can vary slightly, as the hosting infrastructure is shared. Over time, resources are dynamically allocated to other compute runtimes in the same cloud environment, so cold starts can sometimes make latency an unpredictable variable.
No data or state is stored and the runtime disappears after use. However, many providers also offer cloud-based databases and access to external storage. It is often recommended to inject required dependencies into the function as a context, to keep the function as a black-box.
Serverless promises reduced operational costs, since you only pay when a function is being executed (typically in 100ms increments). This makes it great for inconsistent traffic, and cheap to scale because you are sharing infrastructure.
There is also a reduced development cost and an increased speed of development and deployment. The FaaS approach makes services quick to prototype and offers a noticeable speed to market. It also allows for continuous experimentation. There is also very little system administration that needs to occur; mostly just along the lines of account and credential management.
FaaS works with microservice design patterns, which is often a preferred pattern for API-oriented developers.
There is also the potential to be a little bit “greener” given the fact that a given function’s runtime spins down when not in use.
FaaS development tends to work well with other services in the same PaaS environment. For instance, Lambda functions work well with Alexa skills, and Google Functions work well with Android mobile apps and Google Assistant.
Starting with a PaaS vendor denotes a certain amount of third-party vendor lock-in; or, at least a considerable amount of vendor control over the environment. This includes a loss of fine-grained server optimizations and customizations.
Latency and cold starts may be an issue, especially if high-trafficked API endpoints are expected to respond quickly. This generally keeps FaaS limited on-demand requests that allow for some latency, like chatbots or responses to SMS messages, where a little lag time is acceptable.
Multitenancy (architecture in which a single instance of software runs on a server and serves multiple tenants) may be an issue, especially when security is concerned. Even though runtimes are stateless and relatively self-contained, they are still running on shared cloud infrastructure.
There is a relative lack of operational tools for some providers. Implementation, local development, and testing all have challenges. This may make functions difficult to test, especially for integration testing. It can be tricky to develop locally, though Azure and Fission.io have made some things easier in this aspect.
FaaS is not efficient for long-running applications or for applications with uniform traffic distribution, as cold starts and runtime initialization can introduce some undesired latency.
Language runtimes tend to be limited. However, some providers, such as Bluemix, offer the ability to expand available languages. Other providers are working to extend the available languages over time, as well. If vendor lock-in is a concern, consider Node and NPM, as this is the most ubiquitous language across providers.
Function explosion and scope creep can have a large impact on the ability to manage an application. Developers may have to manage hundreds or thousands of discrete functions. The use of a framework to manage these is a must.
I’d like to thank Phase2’s CTO, Frank Febbraro for his contributions to this blog post. We recently co-presented an internal presentation on Serverless and FaaS at P2Con (an annual Phase2 gathering), and much of this material was adapted from that. Frank recently helped me embrace serverless architecture in record time.