Hosting my Hugo Site on GCP with Terraform

This article was written by me. Subscribe to get updates to your inbox

This article appears on my personal website, hosted with GCS and Cloudflare.

What is a Static Site? ๐Ÿ”—︎

A static website is a website that uses pre-built HTML, CSS, and JavaScript.

This means that the website loads quicker, and it can be much easier to create.

This is in contrast to a dynamic site, which renders the website at the time of the request.

Static sites cannot offer some of the features of a dynamic site however they are often

  • faster
  • more secure
  • highly scalable

There are many static website generators out there that make it easy to create a unique website.

The one that I use for my site is Hugo.

Why Use Hugo? ๐Ÿ”—︎

Hugo is a static site generator.

There are many great templates to create website with Hugo.

Hugo allows me to create a great looking site very easily and effectively.

Setup ๐Ÿ”—︎

So, how does this work?

Tools used

  • Hugo
  • Cloudflare
  • Github
  • Terraform
  • Google Domains
  • Github Actions

My website is found here -

Create Site ๐Ÿ”—︎

The first step is to create your website.

Start by downloading Hugo, choosing a template and adding some content.

Copy site to GCS ๐Ÿ”—︎

We need to copy your site into a GCS bucket.

First, we need to create a bucket. (I’m assuming you’ve set up your Terraform and connected it to a backend)

I had to create my bucket with the same name as my domain,

Here is my Terraform for this:

resource "google_storage_bucket" "site_bucket" {
  name          = var.site_bucket_name
  location      = var.region
  storage_class = "COLDLINE"
  force_destroy = true

  uniform_bucket_level_access = true

  website {
    main_page_suffix = "index.html"
    not_found_page   = "404.html"
  cors {
    origin          = [""]
    method          = ["GET", "HEAD", "PUT", "POST", "DELETE"]
    response_header = ["*"]
    max_age_seconds = 3600

# Make bucket public
resource "google_storage_bucket_iam_member" "member" {
  provider = google-beta
  bucket   =
  role     = "roles/storage.objectViewer"
  member   = "allUsers"

Next, let’s create your site.

Run this command to generate your site

hugo -minify

Next, let’s publish your site to your GCS bucket.

Edit your config.toml file in your Hugo site to contain a deployment block.


Next, run this command to deploy your site to the bucket.

hugo deploy

Now, check the bucket you created. Your site files should now be inside the bucket.

Cloudflare Domain Setup ๐Ÿ”—︎

I have used Google Domains to host my domain, but Cloudflare for my certificates.

I connected my site to Cloudflare, and had to add the following rules.

  1. A DNS Rule

Your domain won’t automatically connect to GCS, we need to set that up.

Since I’m using Google Domains, Cloudflare already knows about my google services.

We need to add this DNS rule.


This tells our site to look at Google Storage for the site content.

  1. WWW Redirect

The <WWW.SITE> and .SITE are different. We need to create our site in such a way that these two sites are the same.

We use a forwarding rule.

Forward the https://SITE to https://www.SITE

This set up my site correctly.

CI with GitHub Actions ๐Ÿ”—︎

The finally piece of the puzzle was to setup CI for the site.

To do this, we need

  • Github Actions
  • Service account for Terraform

I have one Github Action for building the Terraform.

And another for rebuilding my site

When we push to the master branch, our site is rebuilt.


Conclusion ๐Ÿ”—︎

This project was a great way to get introduced to building a GCP project and hosting something.

See the full repo for all my code

And subscribe to get updates from me

Connect With Me!

I'll remind you when I post so you don't have to remember


    Sites I Used ๐Ÿ”—︎