Hacking a quick closed-source react static site in aws s3 and cloudfront, with a lambda helper
Roy R.
Posted on November 1, 2022
We all know about deploying a static react build to an aws s3 bucket. We can build a react site, e.g. npm run build
and get an output directory, which we can then serve as a static site, npx serve ./build
for example.
What is the fasted robust site we can hack together easily ourselves, before we go to third-party services like vercel, netlify, and surge.sh (for instance if you are working for a company that does not want to use out-of-aws third-parties for infrastructure) ? A bucket+cloudfront site is a good option. I have been running nigh unbreakdable cloudfront sites that have been up for years without complaint and almost zero maintenance. One caveat is that keeping the caching settings and invalidations correct initially is tricky, cloudfront caches at the edge really really well, so we might want to automate invalidation of the / root for ourselves.
This is where we can have a little fun by using a lambda to automatically trigger on changes to the bucket assets, leaving us with a dead-simple, copy-and-paste - from local folder to bucket - deploy process.
So the first step step is to create a bucket & upload the files to it e.g. aws s3 sync ./build s3://your-bucket-name
, and then we want a robust and wont-cost-much site DNS, which we can do relatively fast using cloudfront:
- Creating a cloudfront distribution
- Set the error pages of the cloudfront distribution to point error 404 at /index.html, error 403 at /index.html, so that the react app can route all urls that don't have static assets at them to the main index page. Set the path at / to have a caching policy of no-cache, must-revalidate, so that people hitting the site will always get a fresh / root result, but we can more aggressively cache other assets because they will get invalidated when we push up.
Creating a lambda watcher to invalidate on bucket changes: https://gist.github.com/supinf/e66fd36f9228a8701706
Trigger the lambda on bucket changes.
S3 is one of the standard triggers for a lambda function, so you can set S3 changes to trigger the lambda invocation.
s3 -> lambda -> cloudfront
- In the first stage of development, you may want to wrap the cloudfront distribution behind a WAF (or WAF2, whatever) so you can control who has access to it while you are doing rapid development. If you don't care who sees or hits the site, skip the WAF, with cloudfront I find you'll rarely need it, your site will be so stable.
Deploy via CI
Because the infrastructure itself will handle the cache invalidation, your CI can simply be responsible for building the assets. In the beginning this could be as simple as having an index.html with hello world in it or you could skip right to react and npm run build
and a github action that runs cp ./src/* ./build
and then aws s3 sync ./build s3://your-bucket-name-here/
.
(You will have to add an aws token secret to your github secrets to allow github action to upload to the bucket)
Posted on November 1, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.