6 minutes
Building my blog part 1
Good evening everyone, in my previous post I talked about building a CI/CD pipeline for my static blog, it’s been a few weeks since then and I have been using the pipeline to make changes to the blog. It’s a really easy workflow, just create a branch make changes submit a pull request wait for CI to pass then merge the pull request which triggers a deployment (I just want to write blog posts but somehow this pipeline is making me feel like I’m just doing my day job :sweat_smile:).
Anyways, tonight I want to talk about my static blog’s architecture and how I built it (we are finally talking about it!), have a look at the diagram below (I hope you like isometric diagrams) to get a visual sense of how it looks like.

The diagram shows that I used a few AWS services to fully host my static website, the AWS services I used are; Amazon Simple Storage Service (S3), Amazon Cloudfront, Amazon Route53, and Amazon Certificate Manager.
How does it all work?
The most straightforward explanation that I can think of to explain this is - the static website is deployed and hosted in a private S3 Bucket, a Cloudfront distribution is then configured to use the S3 Bucket (which hosts the static website) as an origin, and then a Route53 DNS record is created which references to the Cloudfront distributions CNAME.
Now every time a human inputs the Route53 DNS record (in this case jrpospos.blog
) into their browser it should resolve and serve content from my Cloudfront distribution which fetches and caches the real content from the origin which is the S3 Bucket.
Another thing to take note of is if you look at the diagram again on the left section there’s another stack similar to what I just mentioned, this stack is only used to catch any requests going to www.jrpospos.blog
and redirect it to jrpospos.blog
.
I’m confused, where are all the servers/vms?
That’s the beauty of it, there are no servers! well, servers are powering the AWS Services that I used but those servers/vms are abstracted away and this is one of the reasons why I decided to use this architecture; because there are no servers, there is nothing to harden, manage, maintain, secure, update/upgrade and servers are far more expensive to run as you pay per compute and block storage, and much harder to scale.
I could have used a managed CMS solution like WordPress, Ghost, or SquareSpace but even those are a bit more expensive and ultimately, I really wanted to use Hugo to build my static website.
Now that we’ve gone through the architecture at a high level, I will walk you through the process of building the solution outlined in the diagram, to make it easier to explain and follow, I will include terraform and code snippets which you can run.
Prep work
This assumes that you already have an AWS account, create one if you haven’t already also, create an IAM User through the AWS console, and make sure to give it AdministratorAccess (Se note below), enable MFA for additional security, and generate/create access keys for it.

Don’t forget to download the generated/created access keys as you will need them later, clicking on the download button will download a .csv
file containing your access keys, secret keys, and other information.

Let’s make sure that you’ve got all the right tools installed, let’s begin by installing awscli. The installation command below is for Ubuntu and should work for other Debian-based distributions, if you are using other systems head over to the official install docs for awscli.
sudo apt install awscli
Next is we configure awscli
so that it can access our AWS account. Make sure that you populate the values using the contents of the .csv
file that we downloaded earlier.
aws configure
Finally, we install terraform. If you are using other systems head over to the official install docs for terraform.
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
sudo apt-add-repository "deb [arch=$(dpkg --print-architecture)] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
sudo apt install terraform
Buy your domain name
Now that all the preparations are done, it’s time to buy your domain name. There’s nothing special with this step, just go to your domain registrar of choice, it could be GoDaddy, Namecheap, etc. and buy your domain name, you can also buy your domain name from AWS. Have any idea what your domain name will be? Take your time, I certainly took time with mine. Do not buy an SSL certificate for now.
Initialize Terraform
Once you’ve bought your domain name the next step is to initialize terraform, this is so you can use the snippets on the following steps.
mkdir blog-infrastructure && cd blog-infrastructure
touch main.tf
Open the main.tf
file and add a provider section, this tells terraform that we want to provision resources in AWS.
provider "aws" {
region = "ap-southeast-2"
}
provider "aws" {
alias = "useast1"
region = "us-east-1"
}
Notice how I have 2 regions configured above? This is because I want to provision the majority of my resources in ap-southeast-2 but there are global resources that you can only provision when you specify the us-east-1 region. This is also to show you how you can integrate globally spanning resources. Once that is done, the only thing left to do is initialize terraform.
terraform init
Create a Route53 delegation set
The next step is to provision/create a Route53 Delegation Set. A Route53 Delegation Set is a group of 4 nameservers that can be reused by multiple hosted zones within your AWS account. Add the snippet below to the end of your main.tf
file.
# Provides a Route53 Delegation Set resource
resource "aws_route53_delegation_set" "this" {
reference_name = "MyDelegationSet"
}
output "nameservers" {
description = "Update your Domain's nameservers in your Domain Registrar's console."
value = aws_route53_delegation_set.this.name_servers
}
Save your main.tf
file and run a terraform plan
. Make sure you inspect the result before running a terraform apply
.
terraform plan
terraform apply -auto-approve
Once terraform apply
has succeeded it should output the 4 nameservers that were just allocated to you. Copy these 4 nameservers and go to the domain registrar where you bought your domain name, navigate to your domain name and there should be an option to replace the nameservers assigned to your domain name, go ahead and replace these nameserver addresses with the 4 nameservers you just created.
Create your Route53 hosted zone
After creating a Route53 Delegation Set and associating it to your freshly bought domain name, the next step will be to create the Route53 Hosted Zone for your domain name, this will allow you to create records in your domain name.
resource "aws_route53_zone" "this" {
name = "mycoolblog.wtf"
delegation_set_id = aws_route53_delegation_set.this.id
}
The delegation_set_id
associates the Route53 Delegation Set from earlier to your Route53 Hosted Zone, this is so the world can find any records you add to this hosted zone. Make sure you replace mycoolblog.wtf
with the actual domain name you just bought. Add the snippet above to your main.tf
file and run terraform plan
and terraform apply
.
Wrap up
On my next post I will continue to talk about how I built my blog, I will show you how I provisioned an SSL Certificate for my blog using Amazon Certificate Manager with domain-based verification, the S3 buckets for hosting my static blog, the CloudFront distributions, and the DNS records so stay tuned!
:memo: NOTE |
---|
I’m splitting up this post into 2 parts as I want to keep each post as small as possible. |