Your first serverless project is a great time to earn some fresh battle scars. There are quite a few things you might take for granted about instance based solutions that you will quickly miss when going serverless. However, fear not, for there are serverless solutions to many of these needs. Here is the shortlist of some serverless tools and tricks that help replace the need for typical instance based ones.
#1: Serverless “Framework”
Firstly, let me save you some confusion. There are actually three things that often get confused when talking about the Serverless Framework.
- The Methodology: Serverless Architecture (a.k.a. Serverless) is a methodology that is provider agnostic. It does not mean there are no servers involved. It just means there are none that you have to be involved with since it’s the provider’s responsibility as part of the cost of service.
“Serverless computing allows you to build and run applications and services without thinking about servers. Serverless applications don’t require you to provision, scale, and manage any servers. You can build them for nearly any type of application or backend service, and everything required to run and scale your application with high availability is handled for you.” — Amazon
- The Tool: The Serverless Framework (a.k.a. SLS)
A multi-provider command line tool that automates and abstracts away a metric ton of manual tasks otherwise needed to develop, test and manage many of the cloud services behind a serverless stack.
- The Company: Serverless Inc.
The name of the company that now develops and maintains The Serverless Framework. Austen Collins, Founder & CEO, was the original creator of the Serverless Framework.
At the time of writing, the Serverless Framework supports 4 major cloud providers Amazon Web Services, Google Cloud Platform, Microsoft Azure and IBM OpenWhisk.
First, you write relatively simple YAML into a serverless.yml file that defines your functions, events and resources. Then SLS will deploy and provision everything with a simple sls deploy command, or can do things like tail Lambda CloudWatch logs with sls logs -f functionName directly into your terminal.
When using AWS as a provider, SLS converts your YAML into an AWS CloudFormation (CFN) template, uploads it to an auto-created deploy-bucket and then kickstarts the CFN stack creation.
So far, working with SLS has been amazing and even though it is still relatively new to the scene, it has quickly grown as our de facto tool to create, deploy, test our serverless applications. It’s really the catalyst that got us into serverless.
Watch for an upcoming article specifically about the Serverless Framework. In the meantime, check out some of the Serverless Framework Examples.
#2: Use SSM instead of Environment Variables.
SSM stands for Severely Sucking Moniker… well no, it actually stands for Simple Systems Manager and there may not be a very good answer for where the name came from.
(For all other AWS TLA complains, see AWS in plain English.)
All acronym confusions aside, SSM is actually a great cloud parameter store that can be used across multiple stacks. It can also solve a few common CFN challenges like cyclical dependencies and deploy-time limitations.
Just setup an SSM Resource and set it equal to some value…
…then use that param in your lambdas…
Fairly simple but powerful way to manage variables. It may go without saying, but you can also use SLS to read and create SSM params. It’s already solved a number of issues we’ve encountered.
#3: Lambda@Edge can replace your SPA’s .htaccess file
Proper HTTP statuses and pretty urls are definitely something that is easy to take for granted. When a page exists, it should return a 200 OK , when it or an asset is missing it should return a 404 . Simple right?
Also, urls should look like this https://www.domain.com/path/ and not this https://www.domain.com/path/index.html and it should not require 30 redirects. Things that traditionally could be done on the web server/proxy (httpd, nginx) with an .htaccess file or the like.
Unfortunately, S3’s Static Website Hosting currently only partially supports these. However, it really doesn’t cut it for production. The main reason for this is how S3 handles your index.html file.
Many SPA articles suggest setting both the Index Document and Error Document to your index.html .
The Index Document and Error Document dictate which file to serve up when a request is made to a directory /path vs a file /path/file.html , and what to do if there is a request for a file that does not exist.
So in the case of a request to your site like https://www.domain.com/somePath/ it will result in your site loading for the end-user as intended, however, if you inspect the network panel, you should see that the response came back from the server as 404 not found. This is because the folder /somePath/ wasn’t found in S3 and so it served up your chosen index.html as the Error Document, which in turn handles the route and provides the proper page to the user.
There are a number of reasons having all routes (other than the root route) of your site responding as 404s is bad, not least of which are SEO score downgrades, SEM thinking your site is down and removing the ad, and User Experience confusion.
However, is it just fair to say that it’s just plain ugly?
With Lambda@Edge you are able to associate a custom Lambda to run with each request coming into CloudFront (CF)and in that code, make any modifications you like to the request. (similar to what you might do in .htaccess )
Then, when a request is made to https://www.domain.com/somePath/ the Lambda first checks if the path is to a directory or an HTML file and if so, rewrite that request to point to your index.html file. Otherwise, if the request is for an asset it continues on untouched to S3 and succeeds or fails based correctly on whether or not the asset exists.
This also works for things like case-insensitive routes (domain.com/MyPath/ -> domain.com/mypath/ ) and canonical rewrites (domain.com -> www.domain.com ) for the domain. For the canonical solution, standard S3 Static Website Hosting would have you set up two CloudFront Distros backed by a bucket that redirects you over to the actual www bucket. If that sounds a bit convoluted, you’re probably not alone.
Now with Lambda@Edge, you can just rewrite the requests in front of your app as you normally would but without the need of a web server or proxy instance.
When using CloudFront and S3, you may also want to restrict traffic to the bucket to only that coming from the CF CDN. This prevents traffic from accessing the bucket directly, which can impact costs. AWS does not double dip with traffic from CDN and so on the S3 side it is free.
#4: You can’t delete Lambda@Edge functions
Well, up until 26/01/2018 you could not delete them in any way shape or form. Yup. That’s right, once created, you would have had ZERO ways to delete it. Removing the resource from your CloudFormation template would just cause your stack to error. Trying to delete them manually would error as well. Not that it costs you anything to have unused Lambdas laying around, but that quickly gets pretty messy in the console.
There seem to be a few others that thought this odd and so AWS quickly found a way to allow us to delete these manually. Here is it…
- Disassociate the resource from any CloudFront Distros.
Previously dissociated Lambda@Edge functions (prior to 1/26), won’t yet be able to be deleted. It takes about 30 minutes for the system to clean up things such as your replica functions. Once the replica functions are cleaned up…
- Delete it manually.
Not sure why Lambda@Edge seems to have created such issues for something like deletions but it sounds like ironing this one completely out is one of AWS’s priorities. I just hope they provide a way to allow CloudFormation stacks to delete without error or blocking when tearing things down. For the moment though, manual deletes it is.
#5: You can use WAF to White/Blacklist your serverless site…and more
AWS WAF is a web application firewall that helps protect your web applications from common web exploits that could affect application availability, compromise security, or consume excessive resources. AWS WAF gives you control over which traffic to allow or block to your web applications by defining customizable web security rules. — AWS Docs
Since there is no typical web/proxy server, putting development sites behind a simple Basic Auth is not possible. However, with WAF you can setup all kinds of rules with which to block traffic. This is a very small example of the power behind WAF, so it’s highly recommended to go have a quick readout it.
#6: You can build your own CloudFormation Resources
Not all AWS Services are supported in CloudFormation and some are only partially supported. You may have also found yourself wishing some service outside of AWS could be used in CloudFormation templates. Well, both of these scenarios can be solved with CloudFormation Custom Resources.
Custom Resources are really not much more than a Lambda who’s job it is to simply act on behalf of your CloudFormation templates to Create, Update and Delete a specific type of resource defined by you. This Lambda lives independent of the deploys that might use it.
Take AWS Elastic Transcoder, for example. There is currently no official CloudFormation support for the Pipeline and Preset resources needed. However, with little more than 40 lines of code, and the help of the AWS JS SDK, you can custom build that support.
There is also a great helper/boilerplate Custom Resource lib called cfn-lambda, that helps with a number of standard tasks.
Take this same concept and now imagine creating a custom resource for third-party services like Auth0. Now, even with services outside of AWS, you can orchestrate your whole stack from CloudFormation. Pretty powerful stuff.
So that’s it. Just a few things that I’ve found hard to do without when deploying serverless solutions. Hopefully, this will save you some time and effort as well.
Also, thanks for taking the time to read this article. If you have any feedback to clarify facts, error corrections or even just to ask for more info, please do not hesitate to comment.