Serverless: Up and Running
What is serverless hosting?
In 2018, the requirement for a dedicated server running 24/7 seems a bit antiquated. With the invention of AWS Lambda, it is now possible to own and maintain an API application that only exists on-demand, and only costs resources based on what it uses while running. It’s never been cheaper to run an API thanks to Lambda.
To do that, however, there are a handful of hoops that need to be jumped through to get a working application. For the sake of this blog, the tools that will be used are AWS SAM, CloudFormation, API Gateway, Lambda and DynamoDB. With this toolsuite we’ll be able to get a fully functioning API with minimal setup and minimal cost.
Getting started with AWS SAM is pretty easy. For reference, SAM stands for Serverless Application Model, or the way that AWS has decided serverless applications should run. With this model, there’s lots of documentation and helpful links on how to get a serverless application running in production. The base config for a SAM template can be found here:
What the above template does is create an API Gateway entry that maps routes to an express application that is defined in the app/index.js file in your directory. That file should look like this:
And as you can see, the above index file imports and references a minimal Express app defined in an app.js file that can look like this:
With these files/templates, a minimal SAM application has been created. But how do you test that? Well, AWS Sam to the rescue. After installing aws-sam-local, simply type:
sam local start-api --template <whatever-you-named-your-template-file>.yaml
BOOM! You now have a local API running that will run identically to a deployed Sam application. If you go to http://127.0.0.1:3000/test, you’ll get the “Function Created!” response we defined above.
But what if you want to do more?
There’s a ton of documentation online. You can do tons of stuff with SAM/Serverless architectures in general. We’ve found that DynamoDB works so nicely with Lambda that it’s pretty much a no-brainer for serverless architecture. To define a DynamoDB table to work with your SAM template, you would update the template to look something like this:
Now, unfortunately, SAM local does not create any resources other than the serverless functions, so you cannot test your DynamoDB table locally without some extra work. Lucky for you, I’ve done that extra work.
Start by installing Docker, and then pulling the dwmkerr/dynamodb image. For reference, that command is simply:
docker pull dwmkerr/dynamodb
And then run:
docker run -p 8888:8000 dwmkerr/dynamodb -sharedDb
This will start the docker image on the port you’ve defined, and then make it accessible to anyone on your local network. To get that DynamoDB table to have the correct schema, create a schema.json file. Unfortunately, the aws cli does not accept yaml for the DynamoDB create-table command, so you’ll have to convert the yaml that we used to define the DynamoDB table in the updated yaml file above into json. That shouldn’t be too hard, and you can even find yaml to json converters online if you so choose. The one we made looks like this:
Now that DynamoDB is running locally, and you’ve created a schema file, you can run:
aws dynamodb create-table --cli-input-json file://schema.json --endpoint-url http://localhost:8888
This will take the schema you’ve defined and create a table with it in the local DynamoDB instance you have running.
Now, the last piece of config to test your DynamoDB table locally is updating your Express app to look like this:
Now, when you run the SAM local command from earlier, you should have a working Lambda -> DynamoDB connection.
Probably the easiest step, running
aws cloudformation package --template <your yaml> --s3-bucket <your bucket> --output-template-file <an output yaml>
gives you a CloudFormation template locally, as well as a packaged template stored in S3. With those you can easily run the template in CloudFormation, which will generate whatever resources were created in your template file.
Next, you can get into things like:
- Auto Scaling
- Automating deployment of the Lambda
- Building a much more complex API or microservice
- Orchestrating multiple Lambdas/services together
Ultimately this blog post was meant to show an introduction to SAM/serverless. Here at Kong we’ve implemented a similar architecture and had great success with it.