A fast, modern static site—authored in Markdown, deployed to AWS
August 2020 (871 Words, 5 Minutes)
In this post, I’m going to talk about how I set up and deployed a static site that’s fast, modern, serverless, and written in Markdown to AWS. And it cost me $0.00.
The Goal
I wanted to create a website to write about things I’m working on and learning. I only had a few requirements:
- fast;
- inexpensive;
- minimal setup;
- low maintenance;
- lets me write posts in Markdown;
Why not Squarespace, Wix, or Wordpress? ~$15/month for a simple static site and WYSIWYG text editors with 1000 buttons—no, thanks.
Jekyll—the static site
I chose to use Jekyll—an open-source, blog-aware static site generator created by Tom Preston-Werner, one of the co-founders of GitHub. Compared to other options, Jekyll ticked a lot of the boxes:
- Setup is super quick;
- Only needs to be built once, so it’s fast;
- No moving parts that can break or require maintenance;
- Write content in Markdown, which makes things readable in plain text on GitHub;
It only takes a few lines to get set up, and you have a fully functioning static site. This is what the initial bare-bones folder structure looks like:
.
├── _posts
│ └── 2020-08-10-welcome-to-jekyll.markdown
├── index.markdown
├── about.markdown
├── 404.html
├── .gitignore
├── _config.yml
├── Gemfile
└── Gemfile.lock
index.markdown
, about.markdown
and 404.html
are the pages of your site. _config.yml
contains the settings that affect your whole blog, e.g. title, description, baseurl, and the theme. Blog posts go in the _posts
folder, and Jekyll automatically generates these on your site according to date. An example post could look like this:
---
layout: post
title: "Lorem Ipsum"
date: 2020-08-10 08:04:17 +1300
tags: [example, jekyll, markdown]
---
# Example Title
This is an example of a **Jekyll** blog post written in *Markdown*.
## H2
![Cool image](/images/cool-image.jpg)
### H3
| A table | that has | important info |
Within a post you can use Liquid tags to access site-wide variables, e.g. page.path
refers to the path to the raw post or page. As you’d expect, these elements combined make a Jekyll site delightfully readable and simple to maintain! Jekyll also has excellent documentation and plenty of support for migrating content from other popular static site generators.
When you want to start creating content, building the site locally is fast:
Run bundle exec jekyll serve
once and Jekyll will continue to serve any changes as I make them—making the hardest part thinking of what to write.
Deploying to AWS with Amplify Console
To build, host, and deploy my static site, I use the AWS Amplify Console. In a nutshell, Amplify Console provides fully managed hosting for static sites and web apps.
By connecting Amplify Console to a GitHub repo, I can continuously deploy my static site simply by git pushing commits to connected branches. Amplify Console will build the site or app based on the build settings (including running any pre- or post-build commands and tests), and deploy it to Amazon’s CDN.
Amplify Console offers some pretty useful features:
- Branch Auto-detection/-disconnection: lets Amplify automatically connect to branches that match certain patterns, e.g.
feature/*
orrelease*
, and automatically disconnects when branches are deleted. - Domain Management: connect branches to domains or subdomains, e.g. commits to
dev/*
trigger a build and deploy changes tohttps://dev.example.app
. You also get a free HTTPS certificate so your site is secure. - Access Control: add a password to certain sub-domains to work on new features or content without making it public.
- Previews: see a preview of how your site looks on different devices before merging to the production branch.
There are a bunch more features which I haven’t mentioned—these are just the ones I found useful.
When everything is set up, you can see an overview of which branches will be built, any previous builds, and their statuses:
Behind Amplify Console
Amplify Console leverages S3 and Cloudfront to build, deploy, and serve static sites and SPAs. According to their website, Cloudfront has “225+ Points of Presence (215+ Edge locations and 12 regional mid-tier caches) in 89 cities across 46 countries.”, which means it really is as close as possible to the requesting client, and has excellent availability (99.99%). Combined with S3, which has 11 9’s of durability, it’s a pretty solidly supported and well distributed static site.
My setup
For my site, Amplify Console automatically detects branches that match feature/*
or test/*
to build and deploy to the subdomains https://feature.tessapower.xyz
and https://test.tessapower.xyz
.
Previews let me see how my site looks on different devices after building it—I use this as a final checkpoint because merging to master
.
I use Access Control to prompt anyone who tries to access https://test.tessapower.xyz
for credentials, so it’s a safe place for me to test changes in the wild.
My workflow
Not only is this approach modern and extremely fast, it has made my workflow pretty lean. I can create a new post and deploy my website with just one line of code! Here’s what it looks like:
The Stats
Availability | Four 9’s |
Time to set up | 0.5 hours |
Average Latency (worldwide) | ~15ms |
Amount of PHP or JavaScript | 0 lines |
Total cost | $0.00 |
My face | (ノ◕ヮ◕)ノ*:・゚✧ |