Attempting to put my money where my mouth is, I just finished moving
all three of our websites to a new, static-only, HTTPS-secured infrastructure.
Most recent setup
I moved the flyclops.com site to a statically-rendered site some time ago,
serving it over Amazon S3. That went fairly well, but it’s a very minimal
website, and doesn’t require anything dynamic.
The tech blog, which you’re reading now, was hosted on Wordpress, as are most
blogs in this world. But over time, “features” became unnecessary (or even fairly useless) - think
comments. Other features, like caching plug-ins, were nothing more than a means
to an end - near-statically loading sites. But it was kludgy.
Our press kit site was based on
presskit() 2.0, a PHP-based press-kit solution
that is fantastic.
Enter FREE SSL
LetsEncrypt was released out of beta.
This was a turning point. I spend a lot of time making noise about three-letter
agencies and snooping and the necessity of encryption across as much of life as
possible. Considering Flyclops is a profitable enterprise, there wasn’t much
excuse for not having HTTPS across all our sites to begin with. With LetsEncrypt
being production-ready, there was no more excuse at all.
Shortly thereafter, Amazon AWS released
AWS Certificate Manager.
AWS Certificate Manager offers free, auto-renewing SSL certificates for anything hosted on AWS
services. That was now two free SSL services to choose from. Being hosted almost entirely
on AWS, ACM was a natural choice - it’s also easier to manage from a renewal standpoint,
in that there is no renewal overhead as with LetsEncrypt. There are plenty of tools that
make LetsEncrypt renewing almost entirely hands-off, but that would still be something to
What to do with PHP?
Now we had to choose - spin up servers to run PHP-based websites in AWS? That sounded
plenty unnecessary. Instead, I took a closer look at Hugo, the
Go-based static site generator I had glanced at when
I moved the main website to a static site. I quickly ported the static site to
Hugo, and was very happy with the process. (It helps that we recently finished moving
our entire backend infrastructure to Go-written services - Hugo felt like a natural fit
I became determined to get our blog there as well, and installed the
Wordpress to Hugo Exporter plug-in
(thank you all you wonderful open-source devs out there). I exported my content, and spent
about a day or so setting up templates, partials, taxonomies, and archetypes in Hugo. The
process wasn’t entirely painless, but “minimally” painful. All-in-all, easier than I expected.
All that was left was the press kit. Lo-and-behold, I was not the first person to want
to push the wonderful presskit() to a static environment, and I happened upon
dopresskit-static on Github.
A fork and a few tweaks later, and I had all our websites generating static output.
Static sites need static hosting, and S3 was a natural fit… except it really isn’t a totally
natural environment. To boot, you can’t use AWS Certificate Manager-based SSL certificates
with S3. Besides, Amazon has this sweet CDN service called Cloudfront that
would deliver static content so much faster than S3.
First, I generated the following SSL certificates in AWS Certificate Manager:
- One for
- One wildcard certificate for
I set up three S3 buckets (one per site) to act as origins for content. I then set up
three Cloudfront distributions, one for each bucket, with the appropriate CNAMEs. Cloudfront
distributions let you specify:
- CDN origin - an S3 bucket, or BYO
- A secure certificate from AWS Certificate Manager
- CNAMEs for the distribution
- A default file to serve (index.html)
- What to do/serve for different HTTP error codes (404 page). Hint: Depending on how you set up S3 origins, they will return 403 errors for missing documents, not 404.
- Whether to serve both HTTP/HTTPS, HTTPS only, or redirect HTTP to HTTPS (we use redirect)
Distributions take a few minutes to set up, and once they were published, I went into
DNS (conveniently, Route53 on AWS) and
point to the appropriate CDN distributions.
All that was left to do was to set up publishing. At first, I just assumed I’d
push public content to S3 manually as I updated it. But then I took a look at the
“Deployments” capabilities of our git service, Beanstalk by
It turns out, Beanstalk’s deployments are
incredibly powerful and
feature-rich. Publishing, selectively, even, a git branch to an S3 bucket, with pattern-matched
inclusions and exclusions, automatically or manually, was extremely easy to set up.
(Don’t use Beanstalk for git hosting? Check out DeployBot!!)
And bonus - it will automatically invalidate any updated files on Cloudfront! That is spectacular!
Click the image above for a look at all the features
Now I write content, use Hugo to generate the static version of the site, commit the changes to git,
push them to my Beanstalk remotes, and a few seconds later, they’re published!
So now, at least, my money is now firmly where my mouth is - all of our sites are HTTPS only.
To boot, they’re completely static, and CDN-served from an edge node close to you.
Now we can concentrate on more important things, and not worry about constant security updates to
Wordpress and PHP, hosting issues, SSL costs or renewals, site or page speeds, ease
of crawl-ability for web crawlers, and a host of other things.
Not too shabby for a couple days work.