Creating this Blog

Hugo, AWS Developer Tools, S3 & Cloudfront

Posted by Scott on Wednesday, July 14, 2021

TOC

I’ll be honest, I’ve never really had the desire to create a blog before, but I thought I’d give this a go as I was looking through my back-catalog of code and solutions recently and thought; “You know what, I spent quite a lot of time on some of these, and I bet someone else could find them at least partially useful”. So that’s where we are, and what better place to start than explaining how I went about creating this site!

So first-off, I’m not a developer. I know bits of coding, mainly Powershell, Python, Yaml, JSON. But I’m useless really when it comes to websites. I can reverse-engineer code relatively well, but I didn’t want to spend the time copying someone else’s site and making it my own, that’s a recipe for many hours of work, and I knew there must be applications out there for this kind of thing, and my only real requirements were:

  1. I need to build the site using a Windows OS
  2. I don’t want to have to design the site from scratch
  3. I want it to be simple and hostable from an S3 bucket

So after a bit of searching, I stumbled across Jekyll and Hugo, both of which seemed to do just what I was after.

After initially selecting Jekyll and getting it up and running, I realised that although the base theme was ‘fine’, I wanted something more, and all the themes I found online that I really liked, required tons of effort and external services (e.g. Stackbit) to get implemented. I really didn’t want to spend this time getting a nice looking site, I wanted to spend time on the content! So i then decided to go with Hugo, primarily because I found a theme I liked in minutes and it took even less time to get it installed and running.

So with that said, this guide will focus on how I went about implementing this site using Hugo, however I’ll keep the original post I created on using Jekyll here for info.

Similar with Jekyll, I’m not going to go in depth about Hugo and it’s inner-workings as I’m definitely not qualified to do so. So this post instead aims to simply show what I did to get this site up and running, and in time I’ll update it to include the costs, as I’m hoping it’ll be very little!

The end result here aims to be:

  • Easily updatable site (Hugo)
  • Website code maintained in a Git Repo (AWS CodeCommit)
  • Automatic deployment of updated site (AWS CodeBuild/CodeDeploy)
  • Cheap hosting (S3/Cloudfront)

So onto it.


Pre-requisites

This guide assumes you already have the following:

  • A Windows OS
  • An AWS Account
  • Visual Studio Code installed
  • Git installed

1. Set User Permissions in AWS

The first thing we’ll do is setup AWS so we can store and serve our content.

  1. Log in to AWS and select (or Create) your User. We’ll need to give this user access to AWS CodeCommit (which we’ll be using as our Repo where we’ll store our Site config) as well as access to S3 to create Buckets and manage objects within them. So head to the user permissions and attach the AWSCodeCommitFullAccess and AWSS3FullAccess Managed Policies.

    IMPORTANT! - **You should always where possible restrict permissions down to only what is required, I’m using the FullAccess Policies in this guide for demonstration and simplicity purposes.

  2. You’ll also need to generate some HTTPS Git Credentials so we can connect to our CodeCommit Repo later. To do this, head to the Security Credentials tab for your user, and under HTTPS Git Credentials for AWS CodeCommit, click Generate credentials and be sure to download them to a safe place.

    Generate-HTTPS-Git-Creds Git-Creds-Generated


2. Create your buckets

I created 2 buckets for this site (the names have been replaced with examples in the steps below)

  1. Create 2 Buckets as follows:
  • site-bucket - This one is for the site itself (this will contain the contents of a directory named public that hugo will create for us)
  • site-media-assets - This one is for media assets such as images/video/audio
  1. Both of these buckets should both be Public. To do this, once the bucket has been created, select it and head to the Permissions tab, and ensure that all the “Block Public Access” options are unchecked as follows:

    Block Public Access

    Then in the Bucket Policy just below, enter the following policy, ensuring you change the bucket_name to your actual bucket name:

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "Public-Access",
                "Effect": "Allow",
                "Principal": {
                    "AWS": "*"
                },
                "Action": "s3:GetObject",
                "Resource": "arn:aws:s3:::bucket_name/*"
            }
        ]
    }
    

    Perform the above steps for both the site-bucket and site-media-assets buckets.

  2. You’ll also need to set the “Static Hosting Website” config of your site-bucket. Simply select your site-bucket, select the Properties tab, then scroll all the way down to Static website hosting, and click Edit

  3. Enable Static website hosting, selecting the Host a static website option, and set the index and error documents as follows, then click Save changes


3. Create and clone the AWS CodeCommit Repo

Now we have our user and our buckets, it’s time to create our Repo and get it cloned to our local machine

  1. Head over to the AWS CodeCommit Console, and Create a New Repository:

  2. Once the new Repo is created, select it and click Clone URL > Clone HTTPS:

    This will copy the git URL for you to use in Visual Studio Code.

  3. Open VSCode, ensure you have the Explorer open, and select Clone Repository and paste your CodeCommit URL from the previous step:

  4. When asked for Credentials, enter the creds you downloaded from Step 1, and select a suitable location on your local machine to save to (e.g. C:\websites\my-site).

And now we have our version controlled repository setup!


4. Setting up Hugo

Installing Hugo

The first thing you’ll want to do is download the latest Hugo zip from their github page here (it’s the **hugo_extended_…** one, which is hugo_extended_0.85.0_Windows-64bit.zip at the time of writing). You’ll want to extract the contents of the zip to a suitable location, e.g. C:\hugo.

Adding hugo to the Windows %PATH% variable

As hugo is simply a .exe file with no installation wrapper, if you try and run the usual hugo commands in cmd from outside of the c:\hugo directory, you’ll get the usual 'hugo' is not recognized as an internal or external command error. To fix this, we need to add the C:\hugo path to our Windows Environment Variables. To so:

  1. Right click on the This PC icon.
  2. Click on Advanced System Settings`** on the left.
  3. Click on the Environment Variables… button on the bottom.
  4. In the System variables section, find the Path item and double-click
  5. Click the New button.
  6. Type C:\Hugo and click OK.
  7. Click OK at every window to exit.

Open a new Command Prompt window and type hugo --help to make sure the new environment variable works.

5. Creating your site

Create a default site

With Hugo now installed and working, we can create our site.

  1. In cmd, change directory to the parent folder of you newly-cloned repo (e.g. c:\websites\)

  2. Run the following command to generate a new site, replacing <my_site> with the name of your cloned repo

    hugo new site <my_site>
    

    You’re previously-empty repo folder on your local machine should now contain directories and files that hugo has generated for us

  3. At this point, you should be able to run hugo server -D to have hugo publish your site for you to view locally on http://localhost:1313

Adding the ‘Clean White’ theme

So the site it up and running, and although it’s nice, I wanted to give it a better look. So after browsing through the free themes on https://themes.gohugo.io/tags/blog/, I decided on Clean White, which comes with an examplesite directory that we can copy into our site folder for a much fuller foundation to start our blog with.

There’s a great quickstart guide on the github page for getting it setup.

  1. In a nutshell, you simply need to clone the theme’s git repo to the themes folder of you newly-created hugo site. So in cmd, make sure you cd to c:\websites\my-site\themes for example, then run the below command:
git clone https://github.com/zhaohuabing/hugo-theme-cleanwhite.git
  1. You’ll then want to copy the contents of c:\websites\my-site\themes\hugo-theme-cleanwhite\exampleSite to your my-site directory, and replace anything that it prompts you for.

  2. Once copied, cd back to your my-site directory, and run

    hugo serve
    

Your site at http://localhost:1313 should now have a nice new look!


6. Create the AWS CodeBuild Project

Becuase we’ll be synchronising our entire blog code and config to CodeCommit, we need to strip out the important public folder (which hasn’t been created yet, we’ll do that shortly) so only this folder is uploaded to our S3 Bucket which will be serving the site content. To do this, we’ll use CodeBuild to extract the public folder and create an Artifact from it, which will be ingested by CodePipeline and pushed to our Public site-bucket S3 Bucket.

  1. In the CodeBuild Console, Select Build > Build projects and Create build project

  2. In the Project configuration, give it a suitable name, e.g. extract-site-content

  3. Under Source 1 - Primary, select AWS CodeCommit as the provider, the Repo you created in Step 3 as the Repository, Branch as the reference type, and master as the Branch.

  4. Under Environment, use the config from the below, ensuring you use the latest version of the Standard Amazon Linux 2 runtime, New service role and provide a suitable role name. This will create the IAM Role for us and provide the necessary permissions.

  5. Under Buildspec, select Insert build commands, and paste the following code:

    version: 0.2
    
    artifacts:
        files:
           - '**/*'
        base-directory: 'public'
    

    This simply instructs CodeBuild to create an artifact using only the contents of the public directory of our blog folder.

  6. Leave the rest of the options as default, then hit Create build Project

7. Create the AWS CodePipeline

In this section, we’ll be creating a Pipeline that will run every time the CodeCommit Repo is updated. It will push the contents of the repo to CodeBuild, which will extract the _site folder as above, then push that data into our site_bucket S3 Bucket. It will also push the full Blog folder into our site-config-bucket.

  1. Select Piepline > Pipelines and Create new pipeline

  2. Provide a suitable Pipeline name, and create a new service role. You can leave the default name if you wish. Then click Next

  3. On the Source screen, select AWS CodeCommit, then select master branch of your Repo. Leave the other options as default and click Next

  4. On the Build stage, select AWS CodeBuild, then select the Build Project we created in the previous section. Click Next

  5. On the Deploy screen, Select Amazon S3 as the deploy provider, and your site_bucket as the Bucket. Make sure you tick Extract file before deploy, otherwise CodePipeline will upload the content as a zip file, which obviously won’t work as we require the contents to be displayed in the root of the bucket in order for them to be served as a static website.

  6. Review your settings on the Review screen, then click Create pipeline

If you then select your pipeline, you should be presented with something that looks similar to the below (mine has already been run at this point, hence the green ticks)

7. Uploading your site

At this point, we’ve got our CodeCommit Repo created, we’ve got our CodePipeline created and ready to run, and we have our Buckets created ready to store our data. All that’s left to do is have hugo generate our static site files, then upload our site!

Generate static site

  1. In cmd, cd to your site directory, then simply run hugo

    This will generate the all important public folder within your site directory.

  2. Optional - Make the necessary changes to your site/blog posts within VSCode. I won’t go into too much detail here as it’s very much a personal preference on how you want your site to look and what information you want it to contain. There’s some good details in the Configuration sections of the Clean White github page.

  3. Once done, ensure you save and commit all changes locally

Push your site up to CloudCommit

  1. Push your changes back up to the origin CodeCommit Repo. If you struggle with any weird messages about it being unable to find the master branch, there’s a good guide here on fixing that (essentially, git changed it’s primary branch naming convention from main to master in mid-2020)

  2. At this point, you can head to CodePipeline which should now start processing your CodeCommit changes and pushing the data to S3. You can see it in action similar to below:

  3. Once complete, you should then be able to view your site by using the public S3 URL of your site-bucket Bucket.


comments powered by Disqus