Creating a Static Website using Hugo

Creating a Static Website using Hugo

There are many options for maintaining a website these days. There are free options on blogger and WordPress, all the way up to premium services. I hosted this site on Squarespace for many years. The service is good but their templates selection was lacking for a tech blog. I was also underwhelmed with their editor’s performance and it is fairly expensive. I set a goal to migrate my website onto another service to both reduce the cost to maintain and to make it a little easier to update if I am offline.

Mike Tabor wrote a blog about (hosting a static website on AWS S3 storage. This seemed like a low cost alternative that put me in control of all inputs. There was one problem with his requirements: Already have a static HTML page designed and ready to upload. This is a simple assumption but I was migrating from an existing platform that wouldn’t allow a simple export of my data. I had to choose a platform to generate the pages and migrate the data into plain text to feed the program. I tried both Jekyll and Hugo, ultimately going with Hugo as it is more flexible and doesn’t rely on Ruby.

Setting it up

Getting this off the ground does require some effort. There are some essential tools I use to generate the site. First is Hugo itself. The Install Guide is a great step by step guide that can walk you through, though if you use a Windows machine There are specific details to make it easier on you. I would assume the guides for Linux and MacOS are equally helpful.

Install These Too

  • Git - Version control
  • Go - Hugo is written in Go so you need this as well

The guide recommends downloading Git and Go as well. I recommend following those directions, especially if you’re going to use GitHub to share your site files between multiple computers.

Once everything is installed and working per the guide you may want to run through the Basic Usage just to get familiar with how Hugo works. Once you’re comfortable, run through the instructions to build the site

C:\Hugo\Sites\hugo new site

This will create a new folder named Inside that folder many subfolders will be generated.

Folder Structure

The documentation describes each of these folders in detail

├── archetypes
├── config.toml
├── content
├── data
├── layouts
├── static
└── themes

As we’re getting started the folders that are of most important are themes, content, and static. The file config.toml works with themes to customize the site as well.


The theme to your blog impacts how it looks and feels. Any themes should be downloaded into this folder. Once it’s downloaded edit config.toml to choose the theme. Each theme may have configuration items to add to config.toml, check the theme’s documentation for details.


This is where your posts go. Inside this folder I created a couple subfolders: post and page. This separates static sites like About Me and the vROps landing page from my RSS feed for posts. any files saved in these folders will be rendered into HTML with an address


When you run hugo the static contents are saved in the public folder. These files will go to S3 as the content for your site.

The other folders are important but to get started these are the ones you need to know.


My entire blog is now written in MarkDown, a plain text language. Hugo can render Markdown into static HTML and the formatting translates to any device. The formatting is simple and well documented. I use the Atom editor to write. I could use any text editor but I like how an entire project folder can be monitored, it integrates with Git, and it can render a preview on the fly. Notepad++ or even notepad/vi/nano could handle the editing as well.

To start a new post you can either type hugo new post/ or just create a file in your post folder. If you manually create the site you need front matter to tell Hugo what to do, when the post was written, and which catagories and tags to apply.

layout: post
title:  "Creating a Static Website using Hugo"
date:   2018-05-22 9:00:00 -0400
  - "Website"

  - "Git"
  - "Hugo"
  - "Markdown"

This is the front matter for this entry. Your theme may have different required fields, they typically document what needs to be present.

After you have a file created you have to write. Create the content, proofread, move on to the next step once done.


Hugo is great because you can test your site before publishing it. All you have to do is type hugo serve. It will render the site and give you a local url to connect and check it out The site will update dynamically as you edit and save the markdown files. Once the site looks right, move on to generating the content.

Saving the Static Files

Generating a static site is as simple as typing hugo. The site generates and saves in the public folder. These files are the output you feed into AWS.

Using S3

At this point I will assume you’ve went through Mike’s blog about hosting a static site in S3. The files in your public folder need to be uploaded into the S3 bucket for your website. I personally use AWSCLI but you could drag and drop into the AWS S3 web interface just as easily.

After my first push I created a bat file to sync the changed files for me:

aws s3 sync C:\Hugo\Sites\\public s3://

This command works if you have a AWS user with access keys configured in your local machine. Don’t save those into any scripts and definitely don’t upload them to GitHub!

Cloudfront Invalidation

Mike suggests using Cloudfront for the CDN. This works great and is integrated into the AWS Service Catalog. His tutorial makes it very simple. Once it is set up your data caches in their edge locations, speeding up the respose time. The cache expires every 24 hours to keep your data fresh, though that also means an update won’t be reflected for 24 hours. Luckily there is a concept of cache invalidation. You can use the AWSCLI to invalidate individual items or the entire site. There is a cost associated with invalidating too many items per month but using a wildcard only counts as a single invalidation.

aws cloudfront create-invalidation --distribution-id %distID% --paths "/*"

This command will clear the site’s entire cache and regenerate it, immediately exposing your new post to the world!


My site contents are fully migrated. I have control over my site, the ability to edit it offline, and I can change the theme at will. It also costs about 60 cents per month to run. My previous host was charging 12/month to host the site. It has been a great project and I would recommend anyone at least try setting up a static site with Hugo. If you want to pay nothing the static site contents are compatible with GitHub pages, so you can use that to get your content to the world.