(More) affordable static-site hosting with Google Cloud Storage + CloudFront

2 minute read

When it comes to architecture, I try to follow a broadly-applicable adage: “strong opinions, held weakly.” In other words, choose the best option available at the time, justify it soundly and own the decision. When additional information comes along to alter your perspective, do not mourn the old choice. If it’s easy to switch, do so. Otherwise, make trade-offs and adjustments in light of the new information and learn from the experience.

My public cloud of choice is Google Cloud Platform. Choosing a cloud is a big decision for a startup and GCP has, in my strong opinion, the best control plane of any vendor available today. Therefore, it becomes my default for architectural components such as runtime, storage and ingress.

Google Cloud is of course not without its weaknesses. One such case is flexible, cheap CDN at the edge. When hosting a static site (such as this blog!) Amazon CloudFront has a clear advantage. Especially with the advent of CloudFront Functions, which facilitates request and response transforms at the edge, CloudFront remains a first-line tool in my arsenal, even when it simply serves as a proxy to GCP.

Even after exhausting free-tier credits, CloudFront is purely pay-as-you-go, with effectively free TLS certificates from Amazon’s in-house CA. I personally feel that TLS should be a ubiquitous default for any service in 2021; it matters not how “super secret” (or not) the data served may be. It’s therefore super disappointing to see Google offer up a tutorial (for e-commerce content, to boot!) for static site hosting that yields a plain old HTTP site. Especially given how unencrypted content is buried by the Google search algorithm.

So, here’s a quick note on configuring CloudFront with TLS in front of Google Cloud Storage for static sites on GCS.

  1. Set up a CloudFront distribution with a custom origin of storage.googleapis.com and an origin path set to /[your-bukcket-name].
  2. Configure the bucket with read access for allUsers, making the content public.
  3. Configure a CNAME for the distribution, issue and use a TLS certificate from Amazon’s CA. Configure DNS accordingly.
  4. Add this CloudFront function as a client request function on the edge. This function facilitates clean URLs for “subdirectories” similar to what might be done by Apache or Nginx.
  5. Select either a caching policy with no caching (slightly higher cost) or a custom policy that caches origin pulls from GCS for something like 5 or 10 minutes, depending on your tolerances. This is a trade-off between cost/speed and stale content. Allowing CloudFront to cache for any period of time will avail you of conditional requests based on the ETag header sent by GCS.