‘Zip It and Ship It: Serverless Deployments on AWS’ - Think FaaS Podcast
Hi, I’m Forrest Brazeal at Trek10, and this is ‘Think FaaS,’ where we learn about the world of serverless computing in less time than it takes to run a Lambda function. So put five minutes on the clock - it’s time to ‘Think FaaS.’
Serverless gets touted as faster and easier than traditional web development. In many ways that’s true - you don’t have to configure and manage an entire server, and in the best case your total investment of code can be a single handler function in a config file. But in the real world, where code is more complex, the process for building and deploying that code can get a little painful.
That’s because you can’t rely on the established web development frameworks you’re used to, like Rails or Java Spring, to generate code artifacts that work on a web server. Instead, your function source code is usually wrapped up in a zip file, and you upload that zip file directly to the cloud provider.
That’s simultaneously the easiest possible way to distribute a bunch of code, and also the hardest to manage, because that zip file can quickly start to get unmanageable when you start adding third-party dependencies and so on. So, since this is kind of an AWS-focused podcast, let’s look at a few different tips for managing your serverless code on AWS.
Remember that your local dev environment is not much like Lambda.
Lambda functions are tightly controlled - they have no access to the underlying filesystem except for the /tmp directory, and they run on Amazon’s custom Linux distribution. You won’t be able to install packages inside the Lambda function itself. So you’ll have to make sure that any dependencies your function needs, like NPM or pip packages, get shipped in that zip.
This gets a little tougher when you have what are called native or OS dependencies. For example, if you’re writing a Lambda custom authorizer for an API Gateway, you might need some cryptography libraries to decode and validate tokens. And those libraries might have C headers that have to be compiled on Amazon Linux, not on your local dev machine. So without any framework to help you, you would have to spin up an EC2 instance or Docker container locally to get the correct version of your dependencies before manually copying them in your zip file.
This process can absolutely get scattered and very frustrating if you’re approaching it ad hoc every time. Fortunately, some tools have emerged over the last couple of years that really go a long way toward making that zip file creation as painless as possible.
Consider the Serverless Framework….
The Serverless Framework is probably the best known and certainly the most mature of the various deployment tools that have sprung up in the serverless ecosystem over the last few years. They work with multiple clouds, they’re open source, and most importantly, they have a plugin ecosystem that lets individuals like you and me extend the base functionality.
For example, as a Python guy I really like the serverless-python-requirements plugin. It will look at a list of pip packages in a requirements.txt file and load those packages into your zip at deploy time. It’s as simple as running “serverless deploy” at the command line. The plugin even can spin up an Amazon Linux container on your dev machine if you have those pesky native dependencies. There are plugins that let you mock services like Lambda and DynamoDB locally, so you can test your service offline. Trek10 is a Serverless Framework partner, and we’ve contributed a few plugins as well. Very cool stuff.
…or consider using SAM.
The other big player in AWS serverless deployments is SAM, which stands for the Serverless Application Model, and is an AWS tool that’s been gaining a lot of traction over the past year or so. At its core, SAM is an extension of CloudFormation that is “serverless-aware”: it makes the process of creating common serverless resources like Lambda functions, API Gateways and DynamoDB tables easier than raw CloudFormation does, and lets you hook your functions up to events with just a couple lines of config.
SAM has a local development option too, called SAM Local, that supports some local testing and debugging. This service is still in beta and frankly I haven’t had a lot of success with it yet, but it’s worth keeping an eye on.
AWS has also released some other serverless tooling, notably Chalice, which is a knock-off of Flask for deploying Python Lambda functions. But the Serverless Framework and SAM are the big two right now.
So which is best? Each has its strengths and weaknesses. SAM has the advantage of integrating seamlessly with CloudFormation and is starting to get hooks into other AWS services like CodeDeploy. The Serverless Framework has that great plugin ecosystem and is still a lot better at helping you put together your zip file. For now, I’d choose SAM for simple applications and the Serverless Framework if you need more scaffolding to build complex code artifacts. Long term, I would look for SAM to keep getting better and make this choice even tougher. But for serverless developers, that’s a good problem to have.