Hosting Hugo static website on AWS for fun and profit (Part 1)

For some time now I wanted to start blogging again for several reasons. One of them is that I frequently build interesting things on AWS, discover a new open source tool or just experiment with technology and never really keep some kind of documentation for later reference.

Becides that I like giving back something after reading so many helpfull blog posts from other people.

Moving to Hugo

I’ve read some good things about Hugo and it seemed quite easy to get started and extend later on. So I moved my Pelican build blog to Hugo

The major advantage of static generated sites is that you can host them almost anywhere and cheap (even for free). This time I wanted to host it on AWS because I could leverage my AWS knowledge to fully automate it and learn new things while improving the setup.

Overview of the setup

It will be no surprise that the source of my blog lives in a Git repository as this allows me to keep track of changes but also allows me to automate the build and deployment process so all I need to do is commit my changes and just sit and wait for the automation to do it’s job.

For the automation process I wanted something rather simple but still interesting enough to experiment with the various AWS services. Another important aspect was that it needed to be as cheap as possible.

This is an overview of the setup I currently use:

Gitlab Webhook

To trigger the build of the website i use a Gitlab webhook. So whenever I push to the master branch this webhook is executed. This webhook will send a POST request to the http endpoint which is created in API Gateway.

Lambda functions

Initially the webhook endpoint triggered a Lambda function that also did the actual build but there is a time limit before the webhook considers the action failed. The Gitlab webhook docs are not really clear on how long the timeout is, but this made me have to split this up in 2 Lambda functions:

  • one to handle the webhook
  • one to do the actual build

Gitlab webhook function

The endpoint that is used by the Gitlab webhook is an API Gateway endpoint backed by a Lambda Function which takes the payload from the GitLab webhook and checks the X-Gitlab-Token header. If the Token matches, the payload is send to an SNS topic and a 200 http response is returned. If the X-Gitlab-Token doesn’t match a 401 http response is returned and no data is send to the SNS topic.

Hugo build function

This function will download the archive of the repository from Gitlab, download Hugo, perform the actual build of the website and upload it to S3. This function is subscribed to the SNS topic where the previous function sends data (Webhook payload) to. So whenever that happens this function is triggered.

Source code

All the necessary code to deploy this can be found in this git repository. This is still a work in progress but should be quite stable and easy to test. If there are things that are not clear, don’t hesitate to create an issue in the git repository

What’s next

I plan on extending and improve this setup over time. So some of the things I plan to write follow up posts about are:

  • Monitoring
  • Integration with chat tools like Mattermost, Slack, ..
  • Cost