Many of you have asked yourself the following question:

How to set up a simplest site low cost with any maintenance?

I myself went through this big question on which I wanted to answer it through this post.

In this post, we will see how to set up a static website with Hugo on AWS using Terraform.

Spoiler alert: You will discover behind the scenes of the production of this site.

TL;TR: For those who wish to deploy their infrastructures on AWS, here is the repository GitHub

Warning

The website has been updated & upgrade since time. For those of you who are curious, I invite you to take a look at the next chapter of this article

Prerequisites

To understand this post, you must:

To reproduce the example of this blog, you must:

The beginning: What do we need?

To resume our question:

How to set up a simplest site low cost with any maintenance?

For this we need:

  • Simplest site: is often a static web site.
  • No maintenance: brings us to the concept of Serverless.
  • HTTPS: For this, we first need a domain name and a certificate.
  • Low cost: The goal is to pay 0 each month.

1st step: the choice

In our adventure, we need a static website generator and a static website host.

The static website generator

In this post we will see Hugo mainly to discover the product but there is other products such as:

The purpose of this post is not to compare generators.

The static website hosting

There are, several solutions to host your static website for free for example:

Here, the choice of AWS was made because it is one of (if not the) most used cloud provider. It is of course possible to do this on other Cloud Provider such as GCP, Azure, etc

2nd step: A static website on Amazon S3

To host a static website on AWS, we can use Amazon S3 with the hosting a static website feature.

This will yield the following schema (based on AWS’s Paris region): AWS S3 static

Advantage:

  • The architecture is simple

Disadvantage:

Amazon S3 website endpoints do not support HTTPS. If you want to use HTTPS, you can use Amazon CloudFront to serve a static website hosted on Amazon S3.

Pricing:

  • Amazon S3: $0.024/GB per month. It all depends on the size of your site (especially media content). But free if you use the AWS Free Tier

Conclusion : If having an HTTP website is enough for you, you can stop there and start using Hugo (go to step 4). Otherwise, see you in the third step.

Step 3: Setting up HTTPS

Putting an HTTPS on our site is more complex than it seems. Indeed, we must:

  1. Have a domain name
  2. Have a certificate for the usage of HTTPS
  3. Amazon CloudFront to activate the HTTPS

Setting up the domain name

2 choices are available to you:

Info

For my part, I use OVHcloud domain for hosting my root domain name (mehdilaruelle.ninja) and a public hosted zones on Amazon Route 53 for my subdomain (blog.mehdilaruelle.ninja). In my case, I chose Route 53 for my subdomain for simplicity.

In our case, Amazon Route 53 is used. Our Terraform does not create the hosted zone (because it depends on where your domain name is located), so you will have to create and configure it.

Setting up the certificate

For the certificate, we use AWS Certificate Manager (ACM). The advantage of ACM is to be able to renew our certificates automatically and will be used for the HTTPS on Amazon CloudFront.

Pricing :

  • ACM: As we use a public certificate, the use of ACM is free.

In our case, our Terraform does not create the certificate because it takes a little time to issuing it, which can fail our Terraform execution, so we will have to create the certificate manually.

Warning

The certificate must be created in North Virginia (us-east-1) because Amazon CloudFront only use certificates on this region. Consider changing regions to N. Virginia (us-east-1)

Setting up our CloudFront distribution

Once the domain name and certificate are ready, we can start deploying our infrastructure via Terraform.

The infrastructure should look like this: AWS Cloudfront web static

Warning

CloudFront can only be created in North Virginia (us-east-1).

On the GitHub repository, add a terraform.tfvars file with the following variables and values:

  • bucket_name : is the s3 bucket that will be created
  • dns_name : will be the domain name used via Route 53

Note

To do: Change the contents of the backend.tf file with the configuration of your own Terraform backend

Once the GIT repository is ready, run your commands (check your AWS credentials beforehand):

$ terraform init
$ terraform plan
$ terraform apply

The Terraform deploys:

  • A S3 bucket: this S3 bucket will contain our static website. The content thereof is private and accessible only by CloudFront via an Origin Access Identity (OAI). In other words, our users will have to go through Amazon CloudFront and not directly on Amazon S3 to access to our website.
  • A CloudFront distribution: will allow us to use HTTPS on our website, to use a custom domain name, to set up a Content Delivery Network (CDN) and enhance security through the AWS Shield service.

Pricing :

  • Amazon CloudFront: depending on the number of visitors to your site. Around $0.08/GB for data transfer out per month from CloudFront.

Redirects case with CloudFront

The challenge encountered in this deployment is that some URLs in Hugo end like this way: my.website.com/posts/. To make it work, you need to implement a redirect that adds index.html at the end of the URL. For example, if a user enters the following URL: my.website.com/posts/ it turns into my.website.com/posts/index.html.

However, CloudFront does not follow such redirects whether implemented by S3 or otherwise. To solve this, we add a CloudFront function which will transform the URL at the CloudFront level like we want.

4th step: Deployment of our site via Hugo

At this stage, our infrastructure is ready to host our Hugo site. I recommend you to use the Hugo Quick Start to get started on Hugo well.

Info

On my side, I use the theme hello-friend-ng and hugo-notice.

Once your first post has been written and your site has been built using Hugo, you can deploy your site using Hugo. Add in your config.toml the following section:

  [deployment]

  [[deployment.targets]]
    name = "aws"
    URL = "s3://hugo-website-mlaruelle?region=eu-west-3"

Note

To do: Change the URL to your chosen S3 bucket name in your Terraform (used through the bucket_name variable)

Once added, run the following command:

hugo deploy

And now, your website is deployed.

If you want to learn more about Hugo, you can find several tutorials about it.

Feedback on my website experience

The method presented to you is used for this website. Finally, what is the return after several years of use?

Cost

The choice made is not the most optimized in terms of cost because I emphasized flexibility, simplicity and security.

The annual total is between $1 and $2. Add to that $6 if you use a public hosted zones on Amazon Route 53. The costs do not take the annual price of a domain name which depend.

Info

If you use the AWS Free Tier, it costs you $0.

Pricing summary:

Maintenance

No maintenance apart from occasional updates to the themes.

Conclusion

Hugo offers great flexibility for website creation at low cost (or free of charge) and at the same time simple. Considering a free hosting solution and you will not be disappointed.

Warning

The website has been updated & upgrade since time. For those of you who are curious, I invite you to take a look at the next chapter of this article