January 6, 2020
I recently migrated my personal website hosting from a DigitalOcean VPS to Amazon AWS S3 + CloudFront. As part of this, I wanted to use Terraform to manage infrastructure-as-code.
My website is built using Jekyll. Jekyll is a static site generator, which makes it a perfect candidate to serve from a CDN such as CloudFront. In addition to CloudFront, I would need to store the site in S3, update my DNS to point to CloudFront, and generate a TLS certificate that CloudFront can use.
As of early 2021, my website is using Next.js instead of Jekyll, and no longer hosted on AWS.
I had played with Terraform a few months ago, and wanted to try it out in a real-world situation. I followed this tutorial to write the Terraform code needed to accomplish this task.
The generated static site needs to be stored somewhere. S3 is an object storage service designed with 99.999999999% (11 9’s) of data durability and relatively cheap prices.
The Terraform code blow creates a S3 bucket that allows anyone to read objects from the bucket:
To serve my website over HTTPS, I need a TLS certificate for my domain. AWS ACM provides free public TLS certificates.
A CDN caches content at the edges of a network, which helps reduce load on the origin server and reduce and latency due to geographic location. When somebody visits my website, the CDN checks if has the file they are requesting, and if not, will fetch it from the S3 bucket.
I use Google Domains as my DNS provider. In order to route traffic from www.ryanrishi.com
to the CloudFront distribution, I created a AWS Route 53 zone and record:
While DNS propagates, I can get the AWS nameservers from the Terraform state so I can configure Google Domains:
The final step is to deploy the website to the S3 bucket. I use Travis CI to build and deploy my code.
This snippet of code will deploy to the preconfigured S3 bucket whenever a change is pushed to my master
branch:
After deploying, I want to invalidate the CloudFront cache. If I skipped this step, changes to my website may not show up for 24 hours because the default_ttl
for the CloudFront distribution is set to 86400 seconds.
You can see the full Travis CI configuration here.
Moving from my own VPS in New York to a CDN shaved the load time from 1.2s to 200ms. Visitors in California used to have higher latency due to cross-country travel, but now that it is served via a CDN, geographic location plays a much smaller factor—the content will be served from the closest edge of the network topology.
Waterfall when serving from a VPS |
Waterfall when serving from a CDN |
I'm currently running terraform apply
on my laptop— I'd rather run that in a continuous integration pipeline.
Using Terraform was challenging at first, but in the end it seems like a great way to track infrastructure changes. I'd like to continue learning how to manage infrastructure using Terraform, including migrating some other VPSs to EC2/Kubernetes.
You can see the final Terraform code here.