In my earlier post, I shared how I clicked a button to migrate Azure CDN to Front Door and then started being charged a lot for hosting a simple blog on Azure.
So I decided to end my relationship with Azure and move on to greener pastures with AWS. It was not too much work, so why not. I read about AWS Amplify and saw that it was the perfect solution to my problem. So off I went looking for resources to get onboard.
Unsurprisingly, there were plenty of resources online to walk me through the process like this one: Create a static website with AWS Amplify and S3. But that was good for hosting something manually on S3. I didn’t want to manually upload files. I’m too cool for that. I prefer a GitHub workflow that deployed that built and deployed the website to AWS Amplify. And I went off to search again.
This time, surprisingly, there was a post on how to do exactly that! This time it was official Hugo Documentation. Host GoHugo website on AWS Amplify. I used to find the old theme for Hugo documentation more discoverable than the current one. When I searched on Hugo’s docs manually, I couldn’t find what I was looking for. However, when I googled it, I got it. This is a great starting point!
What are the steps to onboard Amplify?
Create a yaml file in the root of your Hugo website
I know that I have pasted the link to the post that already shares this on the official Hugo Website. But my job is to ensure you understand what you are doing. This is not a Github workflow, which is exactly why this is not in your .github
directory.
As you might have noticed, this doesn’t look anything like a Github Actions yaml file. Plenty of new fields.
Key Sections of the Amplify YAML Schema
version
: Specifies the Amplify YAML version.env
: Defines environment variables.backend
: Contains commands for backend provisioning, such as running Amplify CLI commands.frontend
: Contains commands for building the frontend.test
: Specifies test commands and phases.artifacts
: Defines the files and directories to deploy.cache
: Specifies directories to cache between builds.
Warning
The important thing to understand here is that the commands in this file DOES NOT get executed as a GitHub action.
This yaml file has nothing to do with GitHub apart from maybe the fact that you have used GitHub to host all your source code.
The commands are executed inside a build environment managed by AWS Amplify Hosting. This is similar to a GitHub actions runner. It is a Linux based container that AWS provisions for each build and deployment process.
The commands run according to the sequence of phases you define in the yaml file. I realise that I hadn’t mentioned those phases earlier:
prebuild
build
postBuild
All the commands in the file execute relative to the root of your project defined on AWS Amplify. You can write bash scripts and invoke standard Linux utilities. This is exactly what you see in the file I listed above.
What does the YAML do?
The yaml file referenced above creates a frontend
building job with prebuild
and build
phases. The commands listed in the commands
section, all get executed as if it were one single shell script, line by line.
The commands
section has comments all over denoting what each block of commands do, in both the phases. In short, it does the following:
- Install Sass - to support your advanced themes
- Install Go - hugo needs golang installed to run
- Install Hugo
- Sanity check versions of installed applications. Node and npm are already installed on the AWS Linux machines
- Install all node dependencies
- Set a special git configuration to avoid ending up in an error. Read all about it here
- Finally build the website
This results in all the artifacts produced by default in a directory named public
. This is used by AWS Amplify hosting to serve the website.
AWS Amplify
If you are new to AWS Amplify, you can probably find all the information you ever need to know about it from AWS. But in essence it is one of AWS’s services that simplifies the development, deployment and management of modern web and mobile applications. A one-stop shop to quickly get your app out.
Create an AWS Amplify App
I’m assuming you have an AWS account already. Go to AWS Amplify on AWS console and create an AWS Amplify App, connect it to your GitHub repository. If you have the earlier yaml, in the root of the project, then you are good to go.
If you prefer a video - checkout this AWS Amplify - Getting Started by Tiny Technical Tutorials.
Create a hosted zone in AWS Route53
I am assuming that you have a custom domain registered, and you want to use that for your newly created AWS Amplify app. So we need to use AWS Route53, the DNS from AWS to set it up in such a way that typing in your custom domain will take you to this website!
Creating your hosted zone will automatically create 2 DNS records for you:
- NS record - name server record - tells which DNS server is authoritative for that domain.
- SOA record - start of authority record stores important information about a domain or a zone, like the email address of the admin, when the domain was last updated, how long the server should wait between refreshes etc.
Prefer a video of how to do this? Checkout Nader Dabit - Add a custom domain to your AWS Amplify hosted web application.
Configure your domain registrar to use the nameserver records
If you registered your domain on NameCheap - this is how you link your domain to AWS route53 hosted zone
Other registrars will have similar instructions. Beware that DNS propagation could take up to 24-48 hours. So your website could be unavailable for that long if you were going to do this. I didn’t care much as my blog isn’t like the centre of the internet. But if I had an ecommerce store which generates revenue on a daily basis, I would do things differently to ensure there is little or no downtime.
How do we do zero downtime then?
An option available to you in this case is to use Parallel DNS Validation. An overview of steps would look like:
- Pre-validate domain in AWS Amplify using a TXT record for Domain ownership
- Configure AWS Amplify with the custom domain but do not update the live CNAME or A record just yet. AWS will use the TXT record for verification and issue an SSL cert in the background
- Update the DNS records after lowering the TTL of the existing CNAME/A records to under 5 minutes.
- Switch the CNAME/A records and Monitor the propagation
- Clean-up all the Azure resources - get rid of the associated resource group.
Website ready
That’s all there is to it. You could still have a github action run to validate your hugo website before the pull request is merged. If you configure AWS Amplify to monitor your branch for changes, then on every push/merge to that branch, AWS Amplify will automatically trigger a deployment!
I hope that was helpful for those of you getting started with Hugo.