In the first article ever on my website, I will take you through the process of creating a static website really fast using Hugo framework as well as hosting it for minimal cost or even for free (if you are in 12-Months Free period) on AWS S3 and linking it to your own domain name. But first, what is Hugo?

Introduction to Hugo

Hugo is a fast, flexible, and powerful static site generator built using the Go programming language. It is designed to convert content written in Markdown format into a complete website. Hugo provides a range of built-in templates, shortcodes, and functions that allow you to create a customized and feature-rich website without having to write complex code. Its static nature ensures that your website loads quickly and is highly secure compared to traditional dynamic websites.

Building the Website

Installing Hugo

To get started, I first installed Hugo on my computer. Now since I have a Mac and Homebrew installed on it, I used following instructions but feel free to follow instructions for Windows/Linux in the official documentation.

  1. Update Homebrew: Before installing Hugo, it’s a good idea to update Homebrew to ensure you have the latest package information. Run the following command in your terminal:
    brew update
    
  2. Install Hugo: Now that Homebrew is installed and updated, you can install Hugo by running the following command:
    brew install hugo
    
    Homebrew will download and install the latest version of Hugo on your Mac.
  3. Verify Installation: After the installation is complete, you can verify that Hugo is installed correctly by running the following command:
    hugo version
    
    This command should display the installed version of Hugo, confirming that the installation was successful.

Above allowed me to use Hugo’s commands to create and manage my website locally.

Creating a New Site

After installing Hugo, I had now two ways of creating my website, either:

  • create a website using hugo new site command and install a theme on it later or;
  • download the code for an example website from my chosen theme then chop and change it.

And since we are trying to make this website really fast, I chose the latter 😃

Choosing and using a Theme

Go Hugo has a huge catalog of free themes to choose from on their website. I decided to use the Toha theme for my website. Toha is a clean, minimal, and responsive theme with a modern design and several useful features. To use the Toha theme for my site, I simply cloned the github repo of the example site

$ git clone git@github.com:hugo-toha/hugo-toha.github.io.git

Then, I went to the repo directory and ran the hugo server command.

$ cd hugo-toha.github.io
$ hugo server

and voilà the example site was up and running on my local machine at http://localhost:1313/

Chop and Change

Now that I had the example site up and running, I went on changing it to make the website mine.

  • Altering the config.yaml:
    First task was to update the config.yaml placed in the root directory of the repo. It is a configuration file that stores settings and metadata for our website.
    • Updated the baseURL to my domain name:
      • baseURL: https://umair.uk/
    • Updated the title:
      • title: "Umair's Blog"
    • Updated the website background:
      • Placed my own background.png under assets/images/site/background.png
      • Updated the background value like such:
        • background: /images/site/background.png
    • Updated the website logo:
      • Placed my own logo.png under assets/images/site/logo.png
      • Updated the logo -> main value like such:
        •  logo:
              main: /images/site/logo.png
          
    • Disabled features I didn’t need e.g.
    embedpdf:
       enable: false
    ...
    footer:
        disclaimer:
          enable: false
    ...
    
  • Adding my own content to the site:
    All the content (excluding the blog content) on the website lives inside data/en/sections directory.
    • I disabled all the sections that I didn’t want on my website e.g. publications by doing the following:
    section:
       ...
       enable: false
       ...
    
    • Updated other sections’ yamls e.g. about.yaml, experiences.yaml, education.yaml etc

Hosting the website

Building a deployable static website using Hugo

Before I could start on AWS side of things, I needed to generate a deployable website (static files) which can be uploaded to an s3 bucket (I know we can use hugo deploy command to deploy the website directly in to AWS S3 bucket by doing some pre-config, but I wanted to do this manually this time around in order to keep it simple and quick without the required pre-config). I ran the command hugo in my terminal to build my site. The built site was placed in the public directory.

#go to the root dir of your hugo website repo
$ cd hugo-toha.github.io 
#run the hugo command to generate deployable/uploadable site
$ hugo
"Start building sites … 
...
                   | EN   
-------------------+------
  Pages            |  53  
  Paginator pages  |   1  
  Non-page files   |   2  
  Static files     | 781  
  Processed images |  33  
  Aliases          |   8  
  Sitemaps         |   1  
  Cleaned          |   0  
"
#new dir public is created with all the website files inside it
$ ls -l | grep public
drwxr-xr-x   19 [USER]  [GROUP]     608 13 Apr 18:13 public

Creating an AWS S3 bucket to host the website & uploading content to it

Next step is to create S3 bucket to place the above files (within public dir) in. I used the following steps to create the S3 bucket:

  1. Signed in to the AWS Management Console: Accessed the AWS Management Console and signed in to the account.

  2. Opened the Amazon S3 console: Navigated to the Amazon S3 console by searching for “S3” in the search bar or selecting “S3” from the “Services” menu.

  3. Created a new bucket: Clicked the “Create bucket” button to start the process of creating a new S3 bucket.

  4. Entered bucket details:

    • Bucket name: Chose a unique bucket name following Amazon’s bucket naming guidelines. Used a name that reflected the domain or content being hosted (e.g., example-website-content).
    • Region: Selected the AWS region where the bucket was created. Chose a region close to the target audience for better performance.
  5. Configured bucket options:

    • Block public access settings: In the “Block public access settings for this bucket” section, unchecked the “Block all public access” box. This allowed public access to the bucket so that visitors could view the website content.
  6. Created the bucket: Reviewed the settings and clicked the “Create bucket” button to finalize the creation of the new S3 bucket.

  7. Configured the bucket for static website hosting:

    • Selected the newly created bucket from the list of available buckets in the S3 console.
    • Clicked on the “Properties” tab and scrolled down to the “Static website hosting” section.
    • Chose “Use this bucket to host a website” and entered the names of the index document i.e. index.html.
    • Clicked “Save” to apply the static website hosting configuration.
  8. Set bucket policy:

    • Went to the “Permissions” tab in the bucket settings and clicked on “Bucket Policy”. Added the following policy to make the content publicly accessible (replace [BUCKET_NAME] with your bucket name):
    {
       "Version": "2012-10-17",
       "Statement": [
          {
                "Sid": "PublicReadGetObject",
                "Effect": "Allow",
                "Principal": "*",
                "Action": "s3:GetObject",
                "Resource": "arn:aws:s3:::[BUCKET_NAME]/*"
          }
       ]
    }
    
  9. Uploaded the website content:

    • Navigated to the “Objects” tab of the S3 bucket and clicked the “Upload” button.
    • Dragged and dropped the website files, from within the public folder, into the upload area.
    • After adding all the necessary files, clicked the “Upload” button to start the file transfer.
  10. Accessed the website: The website was hosted on Amazon S3. Accessed it using the endpoint URL displayed in the “Static website hosting” section of the bucket’s “Properties” tab. It looked like http://[BUCKET_NAME].s3-website-your-region.amazonaws.com.

Linking it to a domain

Registering a domain name via Route 53

Now I already had a domain name registered and hosted zone setup AWS Route 53 but If you dont already have a domain, AWS Route 53 makes it super simple to register a domain name. Here are the steps to register a new domain name using Amazon Route 53:

  1. Sign in to the AWS Management Console: Go to the AWS Management Console and sign in with your credentials.

  2. Navigate to Route 53.

  3. Open the Domain Registration page: Click on the “Domain Registration” button in the Route 53 dashboard, or click on “Registered Domains” in the left sidebar, then click on the “Register Domain” button.

  4. Search for the desired domain: Enter the domain name you want to register (e.g., example.com) in the “Search for a domain” input field, then click on the “Check” button. Route 53 will check if the domain is available for registration.

  5. Select the domain: If the domain is available, you’ll see a message indicating that it’s available. Click on the “Add to cart” button, then click on the “Continue” button to proceed.

  6. Provide contact information: Fill in the required contact information for the domain registrant, administrative contact, and technical contact. You can choose to use the same contact information for all three contacts by checking the “Use the same contact information for all contacts” box. Once you’ve entered the contact information, click on the “Continue” button.

  7. Enable or disable privacy protection: By default, Route 53 enables privacy protection for your domain, which hides your contact information from WHOIS queries. If you want to disable privacy protection, uncheck the “Enable privacy protection” box. Click on the “Continue” button.

  8. Review and accept the domain registration agreement.

  9. Add to cart and checkout: Review your domain registration order in the cart, then click on the “Checkout” button.

  10. Enter payment information: Choose a payment method, enter the necessary payment information, and click on the “Purchase” button to complete the domain registration process.

  11. Wait for domain registration confirmation: The domain registration process may take a few minutes to several hours. Once the registration is complete, you’ll receive a confirmation email. You can also check the status of your domain registration in the Route 53 dashboard under “Registered Domains.”

After successfully registering the domain, Route 53 will automatically create a hosted zone for the domain. You can then configure DNS records for your domain within the hosted zone.

Creating certificate for my domain

For me to enable https trafic for my website, I first needed to create a certificate using AWS ACM (AWS Certificate Manager). Following are the steps I followed:

  1. Go to the AWS Management Console and navigated to the AWS Certificate Manager service.

  2. Clicked on “Get started” under “Provision certificates” as it was my first time using ACM, or clicked on “Request a certificate” as I had used ACM before.

  3. Chose “Request a public certificate” and clicked on the “Request a certificate” button.

  4. Entered my domain name (i.e., umair.uk) in the “Domain name” field. I clicked “Next”.

  5. Selected the validation method: DNS validation or Email validation.

    • For DNS validation: I followed the instructions provided by ACM to create DNS records and added them to my domain’s DNS configuration. I waited for the DNS records to propagate and for ACM to automatically validate the domain ownership.
  6. Waited for the certificate issuance. Once the domain ownership was successfully validated, ACM issued the SSL/TLS certificate.

Creating CloudFront distribution for the s3 bucket

Next, I proceeded to place my S3 bucket behind a CDN and followed these steps:

  1. Went to the AWS Management Console and navigated to the Amazon CloudFront service.

  2. Clicked on “Distributions” and then “Create Distribution” to create a new CloudFront distribution.

  3. For “Origin domain”, choose my s3 bucket web address e.g. [BUCKET_NMAE].s3-website.[REGION].amazonaws.com

  4. In “Alternate domain name (CNAME)” section, added my domain name i.e. umair.uk.

  5. In the “Custom SSL certificate” section, selected the ACM certificate earlier created from the dropdown list.

  6. Clicked “Create distribution”.

  7. Waited for the distribution to deploy, which took a few minutes.

Pointing my domain name to CloudFront

Now that our CloudFront distribution is setup to use SSL cert for our domain name and is pointing to our s3 bucket containing our static website, its finally time to point our domain to the CloudFront distribution. Following are the steps I followed next:

  1. Went to the AWS Management Console and navigated to the Amazon Route53 service.

  2. Clicked on “Hosted zones” and then my domain name hosted zone i.e. “umair.uk”.

  3. Next I clicked on “Create record” and entered following info:

    1. Record Name: empty
    2. Record Type: A
    3. Alias: Toggled on
    4. Route traffic to: Alias to CloudFront distribution a. [CDN_NAME].cloudfront.net
  4. Finally clicked “Create records”.

  5. Waited few minutes and then tried to access my website on https://umair.uk/

And Horrah, my website was up and running!

I would encourage you to try to create a simple website if you don’t already have one. If you get stuck or need any help, feel free to reach out to me on LinkedIn