The Serverless Framework —  Streamlined

The Serverless Framework — StreamlinedHow I’ve eliminated the pain points I’ve had over the years with the Serverless Framework for my Typescript applications deployed on AWS.The Serverless Framework is a great tool for building serverless applications…


This content originally appeared on Level Up Coding - Medium and was authored by Louis Latreille

The Serverless Framework — Streamlined

How I’ve eliminated the pain points I’ve had over the years with the Serverless Framework for my Typescript applications deployed on AWS.

The Serverless Framework is a great tool for building serverless applications. It abstracts a lot of the complexity away, and allows me to focus more time on my application’s business logic, which is often writing lambda functions. But as I’ve mentioned in a previous article, there’s a few things that I’ve found less ideal with it.

In this article, I’ll guide you through how I’ve structured my latest application, in order to improve the quality of my infrastructure as code. More specifically, I’ll talk about how to

  • Create re-usable blocks of infrastructure to reduce the amount of code you need to write and improve maintainability of your application
  • Hide away nasty CloudFormation functions (such as Ref, Fn::GetAtt, and others) to improve readability
  • Structure your resources into logical blocks of code

All the code found in this article comes from this repository, and can effectively be used as a template to help kickstart any serverless application written with Typescript and deployed to AWS.

Baseline Setup

The very first thing that you should do to get started on the right foot with the Serverless Framework is to use Typescript for your configuration. I’ve said it before and will continue to say it. Somehow there isn’t that much publicity for it over YAML, but this has made a huge improvement in my experience with the framework. This will give you a much better environment to write your IaC in, and will also act as the baseline for every other things I’ll show you in this article. You can even get types to help catch some bugs while writing your IaC, straight in your configuration. Take a look at all the available types here.

Along with that, I would highly recommend using the serverless-bundle plugin. The installation is really simple, and this will eliminate a lot of the cognitive load that comes from properly packaging your Typescript Lambda functions. No more thoughts needed to configure Webpack, Babel, ESLint, etc. The plugin will give you a handful of sensible defaults, and you will get minified, blazing fast functions that only contain what they need (i.e. proper tree-shaking).

Lastly, I would also recommend that you use MiddyJS (I won’t go into the details of how it works; you can read that on their website) for your Typescript functions. This module brings a bunch of middlewares to empower your Lambda functions with things like proper headers for CORS, validating input and output schemas for your HTTP endpoints, automatically deserializing JSON and other content type, proper HTTP errors, and much more.

Re-usable Blocks of Infrastucture

The main thing that you will find yourself adding over and over in your application is probably Lambda functions, so we will focus on that here. Although, this principle can be applied to any other block of resources or configuration that would be replicated, like IAM roles, SQS queues, etc. With this pattern, you will be able to have a functions section that looks like the following:

As you can see, at this point we only get the info that we need. The functions’ name and their dependencies.

Digging into the postMessage function, we have this:

More info specific to the postMessage function, e.g. the endpoint path, the policies, and environment variables.

And then, the generic createFunctionHandler contains all the configuration that will be common to all Lambda functions.

All in all, 3 levels of abstraction, with only the details that you need in each. The createFunctionHandler function is the only code that you would need to modify to make changes that should impact all your Lambda functions. If you need specific details about the postMessage Lambda function, you can find it in its own file. And then, you can clearly see the dependencies of your Lambda functions outlined in your serverless.ts.

Hide Away Nasty CloudFormation Functions

Since the Serverless Framework supports CloudFormation templates, this is usually the go to if you want to creates resources outside the ones that the framework handles for you.

CloudFormation support is great, since you can use all the documentation that AWS provides for each of their services’ API, and easily add new resources to your applications. But if you need links between your resources, you need to use CloudFormation functions like Ref and Fn::GetAtt. And I’ve always found that CloudFormation functions are big, opaque, block of codes, that makes it hard to understand what is going on.

This is why I like to tuck them away, and close to the resource they belong. As you’ve seen above, the dependencies of my Lambda functions are nice, well-named, variables. If I had to use CF functions instead, it would look like this:

Much less readable in my opinion. In my serverless.ts I want to quickly be able to see dependencies between my different resources, and CF functions make it harder.

They do make much more sense close to the resources they belong to though. This is why I put them in the function that defines the resources. This is what the function that creates my DynamoDB table looks like:

In the internals of my DynamoDB table function, I can see that the arn is retrieved using a Fn::GetAtt function, but then the outside world doesn’t need to care about any of that. They simply use the arn variable after calling the function.

If you wonder what the varToString function is, it is simply going to output the name of my variable as a string (i.e. “mainTable” in the code above). See the code here if you are curious. Since I need to use the variables’ name in the CF functions, this function removes the possibility to introduce a bug by renaming my variable but forgetting to change the string in the CF functions. By using varToString, the compiler will notify me of the error.

Structure Your Resources Into Logical Blocks of Code

The last pattern that I will show you will allow to keep your serverless.ts readable as your application grows bigger. Typically, as time goes on, the Resources section of your configuration will grow so big that you will develop tendinitis having to scroll through it. This often happens because when you need to add one thing, say a Cognito user pool for your application, you don’t create one, but a tonne of AWS resources.

Once again, I like to keep my serverless.ts clean, and have it be the place where I can easily see links between my resources. I will then hide the internals of my blocks of resources into separate functions.

Here’s what the function that creates my Cognito user pool looks like (see it in full here):

All the resources needed are defined in there, and whenever I need to know about the specifics of the user pool, I go find them there. The one thing to pay attention to is that I return a resources object that contains all the resources to create. Doing that, I can then use the nice object destructuring feature of JavaScript in my serverless.ts.

Ahhh, so nice to the eyes! One line to know that I have a Cognito user pool in that application. No need to scroll through 100s of line of CloudFormation resource definitions, or try to figure out what each individual resource belongs to!

Conclusion

There you have it! A template for your Typescript serverless functions deployed on AWS! Feel free to skim through the Github repository as there are a few other smaller things in there that make my life easier while programming.

If you have any question, ask away! And if you have your own set of practices that helps you stay productive with the Serverless Framework, please share them in the comments! I’m always looking for ways to improve!

Happy coding!


The Serverless Framework —  Streamlined was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.


This content originally appeared on Level Up Coding - Medium and was authored by Louis Latreille


Print Share Comment Cite Upload Translate Updates
APA

Louis Latreille | Sciencx (2022-04-12T12:36:42+00:00) The Serverless Framework —  Streamlined. Retrieved from https://www.scien.cx/2022/04/12/the-serverless-framework-streamlined/

MLA
" » The Serverless Framework —  Streamlined." Louis Latreille | Sciencx - Tuesday April 12, 2022, https://www.scien.cx/2022/04/12/the-serverless-framework-streamlined/
HARVARD
Louis Latreille | Sciencx Tuesday April 12, 2022 » The Serverless Framework —  Streamlined., viewed ,<https://www.scien.cx/2022/04/12/the-serverless-framework-streamlined/>
VANCOUVER
Louis Latreille | Sciencx - » The Serverless Framework —  Streamlined. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2022/04/12/the-serverless-framework-streamlined/
CHICAGO
" » The Serverless Framework —  Streamlined." Louis Latreille | Sciencx - Accessed . https://www.scien.cx/2022/04/12/the-serverless-framework-streamlined/
IEEE
" » The Serverless Framework —  Streamlined." Louis Latreille | Sciencx [Online]. Available: https://www.scien.cx/2022/04/12/the-serverless-framework-streamlined/. [Accessed: ]
rf:citation
» The Serverless Framework —  Streamlined | Louis Latreille | Sciencx | https://www.scien.cx/2022/04/12/the-serverless-framework-streamlined/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.