My Static Website Blogging Stack on AWS

ยท 3 minute read

I don’t want my blog to be locked in with a specific vendor. My problem is less with the lock-in, and more with the interface. I already have a great IDE for writing Markdown and any website based interface would be a step down from that. Tho that is my personal preference of course, and it doesn’t keep me from republishing either.

Anyway, I ended up with Hugo + CloudFront + S3. It seemed like a great idea at the time - and it still does. Since I am still playing around with AWS CDK, I figured it would be a good idea to modularize my stack and also blog about it.

What does it look like?

I don’t need a complicated stack, which doesn’t mean I can’t have one to have fun with. No, it’s not that bad. I use Hugo, a static website generator written in Go, to compile my writings from Markdown to HTML. The generated HTML is then published to an S3 bucket, which is served from CloudFront. Route53 is used delegate my domain to CloudFront. AWS Certificate Management is used to issue the certificates, so that you can enjoy no browser warnings. In essence:

Static Website Stack in AWS

The details are a bit .. more detailed. For example: I do not publish the generated HTML directly to S3, but use the @aws-cdk/aws-s3-deployment module to do that during cdk deploy. There are also a bunch of glue resources, mainly from the certificate generation via @aws-cdk/aws-certificatemanager.DnsValidatedCertificate.

Show me the code!

The source code of the AWS CDK module lives on Github: https://github.com/ukautz/aws-cdk-static-website. Note: The resulting NPM package is hosted on Github packages as I do not consider it production ready and do not want to contribute to accidental installs… Read up how to use Github Packages hosted NPM packages if you want to use it.

I plan on publishing a “ready-to-go” repository, which lays out a structure for using hugo and cdk in in concert. Like the repo that contains my blog. Once I did so I will update this blog entry. Until then, assuming you are familiar with AWS CDK, I hope the following is helpful to show how to deploy:

import * as cdk from '@aws-cdk/core';
import * as route53 from '@aws-cdk/aws-route53';
import { StaticWebsite } from '@ukautz/aws-cdk-static-website';

export class MyBlogStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.Stack) {
    super(scope, id, props);

    // load or create a hosted zone
    const hostedZone = route53.HostedZone.fromLookup(this, 'HostedZone', {
      domainName: 'mydomain.tld',
    });

    // create all static website infra
    new StaticWebsite(this, 'StaticWebsite', {
      directory: '/path/to/my/hugo/public',
      domain: 'mydomain.tld',
      domainAliases: ['www.mydomain.tld'],
      hostedZone,
    });
  }
}

That’s about it. As mentioned, once I get around to publish that all-in-one repo, I’ll update here. Hope this helps!