Building and deploying a Hugo site with CodeBuild

Jenn - Aug 17 '20 - - Dev Community

If you follow along in the Hugo documentation there are many way to deploy your site. I already had a CodePipeline and CodeBuild set up for my previous Gatsby blog, so I decided to leverage that instead.

The biggest hurdle in doing this, was figuring out what changes I needed to make to my CodeBuild project to make it work with Hugo instead of Gatsby. I searched online until I found a blog post with an example buildspec.yml for me to work from.

I made a few updates to the buildspec.yml and then deployed my site with the following.

version: 0.2

env:
  variables: {}
  parameter-store: {}

phases:
  install:
    commands:
      - echo Entered the install phase...
      - apt-get -qq update && apt-get -qq install curl
      - apt-get -qq install asciidoctor
      - curl -s -L https://github.com/gohugoio/hugo/releases/download/v0.74.3/hugo_0.74.3_Linux-64bit.deb -o hugo.deb
      - dpkg -i hugo.deb
    finally:
      - echo Installation done
  build:
    commands:
      - echo Entered the build phase ...
      - echo Build started on `date`
      - cd $CODEBUILD_SRC_DIR
      - rm -f buildspec.yml && rm -f .git && rm -f README.md
      - hugo
    finally:
      - echo Building the HTML files finished
  post_build:
    commands:
      - echo Entered the post_build phase...
      - echo Build completed on `date`
      - aws s3 sync public/ s3://bucket-name --region region --acl public-read --delete
      - aws cloudfront create-invalidation --distribution-id XX --paths '/*'
artifacts:
  files: []
secondary-artifacts: {}
cache:
  paths: []

I updated my buildspec.yml to use the current version of Hugo 0.74.3 and due to some troubleshooting issues, made the build of the site not be silent.

The biggest change is that I am leveraging the post_build phase instead of sending an artifact back out into the CodePipeline. I sync the built public/ folder with my S3 bucket, deleting everything in the bucket, copying over the files, and making sure everything is public-read. The last line in the phase does a cache invalidation for my CloudFront distribution.

Now whenever I push to the main branch on my Git repo, the site is built and deployed automatically for me. The only issue left is that S3 does not play nicely with "pretty" URLs and I ended up setting my blog to use ugly URLs until I could make a Lambda function to fix it, which will be my next blog post.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . .