In order to make deployments easy and reproducible, we decided to use AWS SAM templates to specify our resources in a declarative way.
In this article I will list some facts, tips and drawbacks we would have liked to know six months ago.
1. Vandium Framework
Once you migrate some CRUD-like actions to AWS Lambdas, you will soon ask for a framework to help you do so. Good news: There is one! Unfortunately Amazon does not mention it in their docs.
For us, the Vandium Framework did a great job. It provides a fluent interface for handling requests with different http methods in a single lambda. So you are able to group the CRUD-Methods for one resource into one lambda without any boilerplate code. Just like you did in your good old controller:
// In your lambda:
exports.handler = vandium.api()
.GET(event => getModel())
.POST(e => createModel())
.PUT(e => updateModel())
.DELETE(e => deleteModel())
Some may say that this is against lambda or SRP concepts, but for us this was the way to go. Furthermore, there are some advantages if we do it like this in relation to my key points three and five.
Also, the Vandium framework has some convenience features like easy validations or error handling and security features like SQL Injection protection for example. See here for more.
So check out if Vandium can save you time, code, or even both!
2. Limited local development and testing
The SAM CLI offers you the possibility to run your serverless applications on your local machine:
sam local start-api
We found this very useful for development and testing. But there is a problem. Right now, many AWS resources can not be emulated in local mode.
You can run your lambdas locally and test them via http. An AWS RDS hosted MySQL database can easily be replaced by a docker container running such a database. For others, such as AWS Dynamo DB, Amazon provides special docker containers for local operation.
However, for some resources such as AWS Cognito, there is currently no way to run them on your dev machine. This means that every time you want to run your code during development, you must deploy to AWS or edit your lambdas in the AWS management console. The same applies to running your tests.
If you’re interested in lambda testing, checkout this article.
3. Slow build times
Each time you change your lambda, you must run the sam build command to apply your changes. Currently the SAM CLI lacks an incremental build mechanism. Every time you change a single line, SAM copies all your lambdas to the output directory.
Once our SAM project had grown to about 30 to 40 lambdas, we experienced build times of about two minutes. Every single time.
So what can you do? The best thing to do is to keep your projects small and lean. This is advisable anyway. Looking back to point one, grouping multiple endpoints in a lambda could also save you some time.
Check and upvote this issue to see if there has been any improvement on this in the mean time.
4. Differing behavior after deployment
As explained in point two, local development is very different from running in the cloud. Never expect a piece of code that runs perfectly on your development machine to work perfectly in the cloud.
The SAM CLI still ignores a lot of configuration you can do in your template. But it’s under heavy development and the support is getting better every day, so always check the new releases.
5. Cold Start delays
AWS Lambdas scale down to zero. This means that Amazon will terminate all running instances after a short time if no request is received.
On the one hand, this is seen as a great advantage, because you don’t pay a single penny if you don’t use your resources.
On the other hand, you will experience a significant delay if your lambda is cold starting. We have experienced an additional two to three seconds when calling a lambda for the first time in a while.
So keep that in mind when you create a lambda that is only used sporadically! Check out this article for some deeper insights and language specific measurements.
With all these in mind, have fun on your way into the cloud!