Functions as a Service (FaaS) is becoming more mature and an alternative to creating Cloud based applications without building and maintaining infrastructure. But can you apply Microservices best practices and patterns to FaaS? Is FaaS prime-time yet? This blog will discuss these questions and will be divided into three parts:
What is FaaS (Serverless Architecture)?
Serverless architectures refer to applications that significantly depend on third-party services (knows as Backend as a Service or "BaaS") or on custom code that's run in ephemeral containers (Function as a Service or "FaaS"). By using these ideas, and by moving behavior to the front end, such architectures remove the need for the traditional 'always on' server system sitting behind an application. Depending on the circumstances, such systems can significantly reduce operational cost and complexity at a cost of vendor dependencies and (at the moment) immaturity of supporting services.
In reality, you do use servers to run your code, you just don't need to provision an actual server and its supporting infrastructure.
FaaS is also sometimes associated with Backend as a Service (BaaS). BaaS features include cloud storage, push notifications, server code, user and file management, social networking integration, location services, and user management as well as many other backend services. BaaS is typically used in the mobile space (MBaaS) where instead of using mobile middleware, BaaS creates a unified API and SDK to connect mobile apps to backend services.
FaaS, in a nutshell, provides an infrastructure abstraction to allow developers to focus more on the execution of stateless code in response to events.
Throughout this multi-part blog I will interchange the terms FaaS, Lambda, Functions and Serverless. FaaS and Serverless are the architecture. Lambda and Functions (same things) are the implementations.
FaaS - The Decomposition of a Microservice
The road to FaaS started with the SOA based monolithic architecture which gave birth to microservices. In a microservice architecture, these applications are decomposed into smaller services to provide better development agility, scale, and improved deployment velocity. FaaS is an additional step in service decomposition to a more granular level of just functions handling events. And conversely, you can create a "virtual microservice" by grouping a set of functions (e.g., AWS Lambda) with the "glue" of an API Gateway.
Figure 1: Microservice Decomposition
No More PaaS?
As Martinfowler.com said, FaaS architecture is nothing more than ephemeral containers executing your code. Unlike a traditional microservice architecture, the developer doesn't need to worry about load balancers, EC2 instances and scaling is totally transparent. Under FaaS, these Platform as a Service (PaaS) operational concerns are no longer front and center which means now there is less friction between development and operations. Developers focus more on the code, not the infrastructure (to a point).
With that said, you are not totally off the hook. For example, if you deploy your Lambda in a VPC (e.g., need secure environment to access RDS) you will still need to build out some infrastructure such as Internet Gateways, NAT, Security Groups. More on this later in Part 2.
Simple FaaS Architecture (AWS Lambda)
The figure below shows a very simple FaaS architecture where the Lambda functions are front ended with an API Gateway. Lambda can write/read from a data source such as DynamoDB which triggers an event that another Lambda uses to generate an HTML page to deposit in a S3 bucket. You will notice there are no EC2 instances required, load balancers, auto-scaling groups, etc., to configure. You are essentially incorporating various AWS services and some functions (Lambda) to build out the solution. The developers' responsibilities are more focused on the actual application and less on infrastructure "plumbing".
Figure 2: Simple FaaS Architecture
Development In A FaaS Environment
Every major cloud platform supports FaaS with each supporting different language implementations. Every cloud platform implements different SDKs with their own set of limitations. The table below shows current languages on which platform are supported. Note: Cloud platforms continue to add new languages all the time
|Java||AWS (Java 8), IBM, Azure (2.x runtime)|
|Python||AWS, IBM, Azure (Experimental - May Be Abandoned)|
|Node.js||AWS, GCP, IBM|
|Ruby||AWS (Using JRuby)|
|PHP||IBM, Azure (Experimental - May Be Abandoned)|
|Bash||Azure (Experimental - May Be Abandoned)|
|Batch||Azure (Experimental - May Be Abandoned)|
|PowerShell||Azure(Experimental - May Be Abandoned)|
Be Concise and Think Atomic
Figure 1. Microservice Decomposition illustrates how FaaS Functions can be thought of as a subset of a microservice domain and should be designed to do a single piece of work in response to event(s). Cloud providers enforce certain restrictions on code size and memory to name a few guard rails. So, bloated code bases can be a real performance obstacle because of memory demands, load times and latency. Make your code scope limited, efficient and light-weight so they load and execute quickly because FaaS functions charge in milliseconds of execution time (AWS). As a result, long running executions are not recommended for FaaS Functions.
One of the problems in developing in a FaaS environment is using a debugger that can access deployed functions in the cloud. The old school way is to write to a cloud log (CloudWatch) and view the output (ugh!) However, there are tools that allow you to first run locally to debug your code before deployment. If you are using the Serverless Framework there is a plugin called serverless-offline (https://medium.com/a-man-with-no-server/running-aws-lambda-and-api-gateway-locally-serverless-offline-3c64b3e54772) to test/debug locally. Trek10 has an open source solution (for NodeJS only) that allows debugging in the cloud (https://github.com/trek10inc/aws-lambda-debugger).
Debugging is an area that FaaS needs to improve on to allow developer's IDEs to have a more seamless debugging integration across any cloud platform and language.
Tools & Frameworks
Because FaaS is relatively new, the tools and frameworks to enable highly productive development are evolving. Open source frameworks like Serverless Framework provide a high level of abstraction to deploy your functions across different Cloud providers. AWS SAM (Serverless Application Model) is specific to AWS but is now opensource and provides similar functionality.
So you have written your code and now you are ready to deploy it to the cloud. Depending upon the cloud platform you can use either the provider's online tools, CLI, SDK (roll your own) or third party tools. Online tools may be OK for testing, but is not acceptable for implementing a good CI/CD automation solution. There is also the use case where there needs to be some infrastructure deployed/configured first (e.g., VPC, NAT, Subnets , etc.) before a function can be deployed. For infrastructure, there are options for using native cloud tools such as AWS CloudFormation templates or even Terraform which provides a framework to utilize a common infrastructure tool that works across many cloud platforms. All of these solutions implement a JSON/YAML template configuration which can be executed via the CLI/SDK (CloudFormation) or executable (Terraform).
The Serverless Framework can not only deploy your functions and define your APIs, it can also be extended to deploy and configure some parts of your infrastructure (e.g., embedded CloudFormation snippets).
So depending upon your deployment needs, you can create scripts to incorporate CLI/SDK along with infrastructure tools (CloudFormation templates) and the Serverless Framework to build (and tear down) a green-field FaaS implantation.
So Is FaaS The Way To Cloud Application Nirvana?
So, up to now, serverless sounds pretty interesting, right? Well, like a lot of things, not one size fits all and it "depends". There are advantages and disadvantages to understand before making the shift. Parts 2 & 3 will go into more detail describing deployment use cases with various gotchas and nuances.
Cost - Reduced operational costs
Reduced Complexity - Fewer infrastructure components (e.g. servers, load balancers) to manage
Decreased Time To Market - Create new apps in hours and days instead of weeks and months.
High Volume Transactions - You can easily isolate and scale them
Dynamic Workloads - Pay as you use them. No need to pay for idle server capacity
Scheduled Tasks - Perfect way to run certain tasks in a scheduled way. Start then go away.
Lack of Operational Tools - Debuggers and monitoring tools could be better
Application Management - As an application (of FaaS Functions) grows in numbers and complexity it can take time to assess, implement and test
Latency - Initial boot up times can be long
Long Running Processes - Charged by milliseconds. Each vendor has an upper limit on execution time (e.g., 300 seconds) so your time is not infinite. Could be expensive if you don't pay attention.
Limitations on Maximum TPS - There can be a limit imposed for maximum TPS for a given function within an account by some vendors (AWS)
FaaS is still an architecture that is evolving. Currently, it provides many benefits such as reduced cost, complexity and time to market for the right application/functional need and is not the silver bullet for all cloud applications. Careful analysis should be performed before selecting FaaS to ensure it meets all of your needs. Also, cloud providers have different levels of FaaS maturity. AWS by far is the furthest ahead now.
FaaS is a beginning step to reduce (obfuscate) the complexities of standing up infrastructure to support an application or perform simple tasks. It does this by eliminating the management of some of the common infrastructure components (e.g., servers, load balancers). As developer tools for FaaS improve, it will provide a better developer experience for them to quickly deploy/test their applications.
In Part 2 I will discuss applying Microservice Patterns & Best Practices with FaaS to a sample use case implementing AWS Lambda.