Using AWS S3 and Hugo to Create and Host a Static Website
Tags: aws, hugo, s3, terraform
Published: 2023-10-07 09:20:02

In this blog, I'm going to guide you how to create a static website using AWS S3 and Hugo. The demo application is deployed using Terraform and I assume you have basic knowledge about Terraform, Hugo, Github Actions, and AWS S3 Static Website Hosting, etc.

**[What is Terraform?][]**

Terraform is an infrastructure as code tool that lets you build, change, and version cloud and on-prem resources safely and efficiently.

**[What is Hugo?][]**

Hugo is a fast and modern static site generator written in Go, and designed to make website creation fun again.

**[What is Docsy?][]**

Docsy is a [Hugo theme module][] for technical documentation sites, providing easy site navigation, structure, and more. In the demo, I use **Docsy** theme component as a Hugo module. Repo [Static WebSite using Docsy in AWS S3][] is generated from official [docsy-example][].
You can clone/copy the `docsy-example` and edit it with your own content, or use it as an example.

**[What is GitHub Actions?][]**

GitHub Actions is a continuous integration and continuous delivery (CI/CD) platform that allows you to automate your build, test, and deployment pipeline. You can create workflows that build and test every pull request to your repository, or deploy merged pull requests to production.

**[Hosting a static website using Amazon S3][]**

You can use Amazon S3 to host a static website. On a static website, individual webpages include static content. They might also contain client-side scripts.

The blog covers two sections:
- Deploy S3 Bucket using Terraform.
- Deploy Static Website Content using Hugo.

## Deploy S3 Bucket using Terraform
Repo: [Terraform S3 Static Website][]

As we use AWS S3 bucket for static website hosting, in this demo, I use Terraform to define and create AWS S3 bucket related resources. There are two options for the deployment.

### Deploy from Local

Follow the [terraform-examples][] to setup local environment to deploy Terraform resources, including
- Install Terraform CLI
- Install AWS CLI
- Setup AWS Credentials

Then, use `make` commands as below for deployment.

```bash
# Create a Terraform plan named `tfplan`
make plan

# Apply the plan `tfplan`
make apply

# Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
# 
# Outputs:
# 
# website_endpoint = "<static_bucket_name>.s3-website-<aws_region>.amazonaws.com"
```
At this point, you will get 404 Not Found if access the website via **website_endpoint** as above. After static content get uploaded to bucket, you should get the rendered content after refresh the page.

### Deploy from GitHub Actions

Or, you can follow the [Setup GitHub Environment for GitHub Actions Workflows][] to use GitHub Actions to deploy Terraform resources with [deploy-static-content.yml][] workflow. 

## Deploy Static Website Content using Hugo

Repo: [Static WebSite using Docsy in AWS S3][]

As mentioned before, the above source code repo is generated from [docsy-example][]. I did two main changes after repo created.

### Configure Hugo Deployment

Add below configuration in `hugo.toml` file. Replace `<static_bucket_name>` with the `static_bucket_name` variable you provided in Terraform project source. You should create your own bucket. 

```toml
# Hugo deployment configuration

[deployment]
[[deployment.targets]]
name = "dev"
url = "s3://<static_bucket_name>"

[[deployment.targets]]
name = "prod"
url = "s3://<static_bucket_name>"
```

Then, create dedicated Github Actions workflows to build Hugo project and upload the static website content to S3 bucket in specific environments.

You should configure AWS credentials secrets from GitHub console following document [Setup GitHub Environment for GitHub Actions Workflows][], then update `STATIC_BUCKET_NAME` in env block in workflow yaml file.

The workflow is automatically triggered. After a successful build, access the static website via http://<static_bucket_name>.s3-website-<aws-region>.amazonaws.com

In this demo, access below website via http://docsy-portal-prod.s3-website-ap-southeast-1.amazonaws.com.

![Website Screenshot](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mb61aea2tta4wn3wa7np.png)

## Advanced Configuration

In a real project for static website hosting using AWS S3, you should think about more complex configurations.

1. Setup a CDN using AWS CloudFront to secure and improve the performance following https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/getting-started-cloudfront-overview.html.
2. Create a staging/pre-production environment in order to validate the change of content before delivering the final content to users/customers.

Done. Thanks for reading.

[Terraform S3 Static Website]: https://github.com/camillehe1992/aws-terraform-examples/tree/main/s3-static-website
[Static WebSite using Docsy in AWS S3]: https://github.com/camillehe1992/static-website-using-docsy-in-aws-s3
[What is Terraform?]: https://developer.hashicorp.com/terraform/intro
[What is Hugo?]: https://gohugo.io/about/what-is-hugo/
[What is Docsy?]: https://github.com/google/docsy
[What is GitHub Actions?]: https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions
[Hugo theme module]: https://gohugo.io/hugo-modules/use-modules/#use-a-module-for-a-theme
[docsy-example]: https://github.com/google/docsy-example
[terraform-examples]: https://github.com/camillehe1992/aws-terraform-examples/blob/main/README.md
[deploy-static-content.yml]: https://github.com/camillehe1992/aws-terraform-examples/blob/main/.github/workflows/s3-static-website-apply.yaml
[Hosting a static website using Amazon S3]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/WebsiteHosting.html
[Setup GitHub Environment for GitHub Actions Workflows]: https://github.com/camillehe1992/aws-terraform-examples#setup-github-environment-for-github-actions-workflows