Going serverless with AWS S3 and CloudFlare
A while back, while developing the new Monitive, we separated the application into two separate parts...
A while back, while developing the new Monitive, we separated the application into two separate parts:
- the API backend which does all the heavy lifting, checking user’s sites and sending alerts, crunching numbers and providing statistics.
- the client-facing web-app, which is basically a VueJS application that users see when they sign in and manage their monitors.
When figuring out where to deploy the web-app, I realized that we don’t actually need a server to host it. Amazon’s S3 storage service combined with CloudFlare’s CDN might just be everything we need. This was even better than I’d hoped, because using CloudFlare’s Always-On feature, our web-app would be up and running even if Amazon S3’s service went down. On the other hand, if CloudFlare went down, so would our web-app; however, this isn’t a very big issue because sites would still be monitored — only the management app wouldn’t be accessible.
I read a few articles (one, two, three) and found out the CloudFlare works like a charm with S3. Serving static websites all over the world took just a matter of minutes to set things up.
All the details are covered by the articles linked above. Since we use GitLab for CI, what we did to get all this set up was something along these lines:
- AWS: Create a new S3 bucket name that matches the domain name where the web-app will be served from.
- AWS: Set the bucket to public read.
- AWS: Add a Public Read Bucket Policy.
- CloudFlare: add a CNAME DNS record towards the S3 public hostname.
- CloudFlare: set page rules to enable SSL and Always-On.
- GitLab: build the production-ready VueJS app
- GitLab: deploy to S3 via AWS CLI
Done! Fast deployment, highly efficient app serving and zero server maintenance.
Bonus 1: Smart caching
When I was only thinking about this setup, I thought that after each deploy, I’d have to call some API cache-invalidation route from CloudFlare so that users would get the newly released version and not the old cached one. But after everything was set up, I found out that CloudFlare’s caching system works great with S3, and sent “If-Modified-Since” headers based on the information provided by the S3 service, which meant there was absolutely nothing for me to do regarding cache invalidation. If any user’s browser had an older version it would just request the newer version, headache-free.
Bonus 2: AWS S3 Monitoring
Another nice thing that came along was an AWS CloudWatch dashboard where we can see request times, types, code, and bytes downloaded or uploaded. This gives us a good idea of how the web-app serving behaves.
Bonus 3: Lower bills
Amazon S3 bills on usage, so more bandwidth and more requests automatically means a bigger bill at the end of the month. CloudFlare, on the other hand, doesn’t bill on usage unless you use some of their features that measure and bill on bandwidth. This combination is truly wonderful from a billing perspective, as most requests would hit CloudFlare’s cache and only a fraction of the bandwidth hits S3.
Bonus 4: Staging deployment
As the flow of setting up a deployment is so simple, and me being a huge fan of continuous-deployment, it was really easy to also create a staging deployment, where production code would automatically be deployed from the master branch with zero effort.
I know that this is not some innovation that I’ve singlehandedly invented, but it serves as a magnificent solution to providing a great service for our world-wide users while keeping costs and maintenance to a minimum. No
nginx configuration, proxies, CDN set up or any server management at all. Just plug-and-play!
So, if you’re building a React, Angular or VueJS web-app, going serverless is definitely a great option. For Monitive, it’s already having a major pay off.
Want to check out the new Monitive? Send us a message and we’ll set you up with an invitation code. I’m really curious what your thoughts are on what we’ve been working on for the past two years.
–Photo by Alejandro Alvarez on Unsplash