I am a HUGE fan of serverless architectures. This new type of compute not only opens up more possibilities for developers, but can support highly-scalable, complex applications for a fraction of the cost compared to provisioning virtual servers. My first question when planning a new application is always, “Can I build this with serverless?” Spoiler alert, the answer is almost always YES!
I’ve been building serverless applications since the release of AWS Lambda in 2015, so answering the question above is pretty easy for me. However, a lot of people I talk to who are new to serverless often have many questions (and misconceptions). I want you to be successful, so below I’ve create a list of 10 things you need to know when building a serverless application. These are things I wish I knew when I started, so hopefully they’ll help you get up to speed a faster and start building some amazing applications.
1. You should use a deployment framework
All of the cloud providers give you a number of CLI and web-based tools to configure, deploy and manage your serverless functions. AWS even has their own Serverless Application Model (SAM) that lets you configure serverless resources. Many developers have built their own deployment pipelines for pushing serverless code to the cloud, but nothing compares with the completeness, ease-of-use, and stability of the Serverless Framework. With a few minor configurations, you can publish functions, configure resources, and completely manage your entire development workflow. The Serverless Framework integrates with all major cloud providers and is the most valuable tool in my serverless arsenal!
2. You’re still responsible for application level security
A cloud provider’s shared responsibility model extends much further with serverless functions than it does with virtual instances. Even though we may no longer be responsible for OS-level security, we as developers still need to take responsibility for the security of our applications. Traditional approaches with WAFs (web application firewalls) only partially address the problem. Serverless applications can go well beyond HTTP and respond to several different types of events. This creates new attack surfaces by accepting untrusted input from logs, SMS messages, IoT devices and more. Ory Segal has a great talk about this from Serverless Days TLV 2018 here: https://youtu.be/M7wUanfWs1c. You can also read Securing Serverless: A Newbie’s Guide for a crash course on securing your application.
3. Third-party dependencies should be scanned for vulnerabilities
Even with traditional applications, third-party packages should always be scanned for vulnerabilities before used in production. A compromised dependency can not only leak data, but can exploit server resources for nefarious purposes. This can be exacerbated with serverless applications because of their ability to scale quickly (sometimes without limits). It’s also difficult to detect a compromised function since serverless applications have limited observability. In the summer of 2017, a post on Github describes how an exploit allowed nearly 54% of the NPM ecosystem to be compromised. NPM now provides their
npm audit feature, which helps, but it still isn’t foolproof.
4. DevOps is still a thing
While the general notion that you don’t have to “provision, manage, patch or update” servers is true, there are still several cloud configurations that need to be applied and managed in order for your serverless functions to run optimally and securely. Function level configurations, such as memory capacity and execution limits, are easy enough to manage, but when building your application, there is a heck of a lot more to think about. VPC configurations, security groups, Internet gateway configurations, access to other resources, etc. all take time and require deeper knowledge of your cloud provider to properly configure.
5. Parameter stores are great for shared secrets
This isn’t specific to serverless, but since serverless lets us break up our applications into really small pieces, making sure passwords, API keys and other shared secrets are accessible (but properly secured) can be a bit of a challenge. Obviously we don’t want to check them into our source repository or let them sit on developers’ machines. Using a parameter store (like AWS Systems Manager Parameter Store) makes this process extremely easy and keeps all of your important credentials locked down.
6. You can reuse persistent connections
A common complaint of serverless architectures is the cold start problem. Since functions are loaded on demand, they require extra time to load into the container on first use. Cloud providers keep functions “warm” for several minutes so that they can respond more quickly to subsequent requests. This not only reduces latency, but also gives us the benefit of reusing data and connections from those functions. Serverless applications will “freeze” connections to databases, caching clusters, and more, allowing you to save valuable time by not having to establish new connections on each invocation. See How To Reuse Database Connections in AWS Lambda for more information.
7. Serverless is designed for microservice architectures
With the advent of container services, like Docker, developers gained the ability to break up applications into smaller parts. This allowed highly-specific containers that were tailored to each part of the application’s workload. Serverless takes this concept even further, allowing developers to break their applications into even smaller parts with much more granular control. Well-designed applications can take advantage of event-driven functions to handoff workloads that effortlessly scale to meet demand. Even complex APIs can be broken into several smaller functions to ensure separation of concerns. I wrote Lambda API, a lightweight web framework for AWS that makes routing HTTP events a lot easier without all of the dependencies and overhead of other web frameworks.
8. Continuous scaling has its limits
One of the biggest benefits to serverless architectures is the ability for it to scale almost infinitely on demand. By running hundreds or thousands of containers in parallel, a properly configured application can gracefully scale to meet almost any amount of load. The problem is that many of the backend services that are needed to support your application aren’t as robust. Even if you are using scalable datastores like DynamoDB, you still need to provision throughput for read and writes. Burst capacity may support short spikes, but larger, sustained loads will require adequate provision planning. If you are using relational database backends, connection limits can quickly be reached which can cause complete outages if not handled correctly. Some of this can be mitigated by using a good caching strategy. See How To: Manage RDS Connections from AWS Lambda Serverless Functions for some ideas for addressing these issues.
9. Observability is less than ideal
Unlike traditional, server-hosted applications, serverless applications typically run in containers managed by your cloud provider. This means that you don’t have access to the underlying infrastructure that runs your code. In most cases, basic logging needs to be managed by the application, which can add unnecessary overhead and code complexity. AWS provides their X-Ray service which gives you the ability to trace requests and analyze issues, but it still requires code level integration as opposed to traditional agents and daemons running behind the scenes. Yan Cui has a series on serverless observability that is worth exploring to learn more.
10. There are a lot of vendor options
AWS Lambda, Microsoft Azure Functions, IBM OpenWhisk Cloud Functions, Google Cloud Functions and Webtasks are some of the native serverless cloud platform offerings available to developers. Each of these cloud providers have robust offerings that manage the function containers for you. If you’d like to host your own environment, or you need more control over the underlying infrastructure, Kubeless, Spotinst and the Fn Project are some popular choices. While choice and competition are certainly a good thing, it also comes with the caveat that each service implements things somewhat differently. Choose wisely. There is a great post by Nick Gottlieb on the Serverless blog that addresses the issue of data portability and vendor choice.
You’re ready to go serverless…
There you go, 10 things that should help you accelerate your serverless journey. It really is amazing what you can build using this technology. Plus, the cloud providers are adding more functionality and services every day to make serverless even more powerful. I’m excited to see where this will take us and what types of problems will be solved. Good luck, and I hope you enjoy building serverless applications as much as I do.
Did I miss something important? What are some of the lessons you’ve learned building serverless applications? Let me know in the comments and I’ll be sure to add them to this post.