Building This Site

This is a static (for now) site built using the Hugo framework with the Relearn theme. The front end source code is available on my github. The application is deployed to an AWS S3 bucket, distributed using AWS CloudFront as a CDN, and the domain name is registered through Google Domains (RIP).

Info

This is the current architecture, but it will certainly change over time. I haven’t decided yet if I’ll pin this blog post and update it as the site develops or just make new posts.

Install Hugo locally

This is my first time using Hugo, and I really like it so far. The quickstart guide got me up and running locally without much fuss. I chose the Relearn theme because I liked the minimal styling and the docs features. Most of the time spent in this step was fiddling with customizations like the favicon and logo.

Once the dev version of the site is working, you can use the hugo command to build a production version of the app (which is what we’ll host on S3.)

Create AWS account

Since I’m hosting the site in an S3 bucket and distributing with CloudFront, we need an AWS account to create those resources. Create an account here.

Warning

You’ll need to provide a credit card number when you sign up, so be aware and don’t run up a huge cloud bill on accident. AWS has a free tier, and the services I use in this version of the site cost fractions of a penny per month, but if you’re going to experiment it’s a good idea to make sure you shut down any running services when you’re done.

Create S3 bucket

I followed a tutorial to host a static website on S3 and configure public access. At the end of this step we’ll be able to access our new site on the internet (but only over http and at a not particularly memorable URL.) At this stage, I’m configuring my AWS services through their GUI as I learn my way around, but we’ll want to make the process more streamlined and programmable eventually.

Configure AWS CLI

We set the initial production version up using our root AWS account and manually clicking through the GUI. It would be a pain to manually redeploy the website in the GUI every time we create a new blog post, and it’s not a very good security practice to use the root account to manage all our services.

We can address both of these issues by installing the AWS CLI and creating a profile with just enough permissions to perform the tasks needed to manage our website.

If we install the CLI and configure it to use SSO and the IAM Identity Center, we can deploy new versions of the site using the command AWS_PROFILE=<my-profile-name> hugo deploy. In order to do that, we also need to add our S3 bucket as a deployment target in our projects hugo.toml file.

Set up CloudFront and serve from CDN

We’re still serving our website directly from our S3 bucket, which doesn’t support connections through https.

The next step will be to setup an AWS CloudFront distribution. This will cache our website across multiple AWS regions, meaning lower latency for end users and the site can be accessed through https. Once our distribution is set up to point to our S3 bucket, we also need to add the CDN to our hugo.toml file. hugo deploy will invalidate the cache by default so that the newest version of the app is served to users immediately.

Set up DNS and TLS certificate

The site is almost working as we want, however we can still only access it through hard-to-remember AWS URLs. First we need to purchase a domain name (I purchased samlawler.com from Google Domains). We can then update DNS records through Google Domains (or whatever domain registrar you used)to point traffic for our URL to the CloudFront distribution we set up in the last step. The DNS records need to be updated for each fully qualified domain name (i.e. samlawler.com AND www.samlawler.com). The website should now be accessible on the internet over HTTP, and served from our CDN. We can verify that it’s being served from the correct location in our AWS CloudFront console.

However, if we try preface our URL with https:// our browser will give us a warning that the site should not be trusted or reroute our request to use HTTP. In order to use HTTPS we need a TLS certificate. You can request a TLS certificate through AWS Certificate Manager. Again, you need to request a certificate for both URLs with and without the www.

Info

Once you’ve requested the certificate in AWS, you need to open the certificate in the AWS console to see the IP addresses to add to your DNS records in order to verify that you are the owner of that domain name.

Next steps

This is just the initial working draft of this site. As I learn more, I’ll try to incorporate my learning into new features of the site itself, or other working demos with write-ups on this site. If the site architecture itself changes, I haven’t decided yet if I’ll update this post or just create a new one, but we’ll see.

Some ideas are to containerize the application with Docker, define and manage the infrastructure with Terraform, create some more web app demos and add them as subdomains, and implement some other features on the core site like hosted email or comment sections. If you have other requests or ideas, please let me know!