I knew the day would come that I wouldn’t be beside my computer to make a post and manually publish it on my website. Since I’m going on vacation for ten days, I had to find a solution to schedule posts and publish them at specific dates.
I want to keep this website as simple as possible and to have it all serverless. That way I don’t have to worry about security, maintenance, updates and similar. I’ve already written about what AWS services, I’m using, and I’m adding CloudWatch Events (besides Logs) to the tech stack.
Hugo builds a static website, so in order to publish something we need to run hugo
command and it will output public
directory with our website in it. This post explains the process of building the project using AWS CloudWatch at
specific times.
How to Set Up a Cron Job to Build The Project
We’ll reference official AWS documentation for CloudWatch Events with CodeBuild, since it has almost everything we need to set up a cron job. The only problem with documentation (I had), is that I can’t find anywhere CodeBuild Project ARN (Amazon Resource Name), which is step 5 of the documentation. After we find the ARN, you can go back to official documentation and follow along.
How to Find CodeBuild Project ARN
Go to AWS CodeBuild, choose Build History, and choose a build from the project we want. If you don’t have any builds, I recommend you create at least one, since we need it. Click on the one item in “Build run” column (like in the picture below).
You should see the information about the build, the information from there we need is “Build ARN”.
We’ll take the Build ARN and modify it:
arn:aws:codebuild:us-east-1:123456789012:build/my-demo-project:7b7416ae-89b4-46cc-8236-61129df660ad
We’ll remove the UUID on the end, and rename the “build” part to “project”.
arn:aws:codebuild:us-east-1:123456789012:project/my-demo-project
You can see more info about AWS ARNs here.
Now that you’ve created a CodeBuild ARN, go back to official AWS documentation and finish the setup.
How to Schedule Posts in Hugo
Next step is to set a date at which we want post to be published in Hugo. We just have to add publishDate
to front
matter.
For example, this post is scheduled for September 1st 2019 at 16:00 GMT, I’ll just add:
publishDate: 2019-09-01T16:00:00+00:00
When we run hugo
command, the publishDate
variable must be in the past for Hugo to build that post. So if I schedule
cron and publishDate
at same time, I should get few seconds delay on CodeBuild, which is enough for the publishDate
to be in the past and it will be built.
Workflow
If you’ve read my post about
hosting serverless hugo on AWS,
you’d see that I have a GitHub project that has Git WebHook on it. For those
of you who don’t know, Git WebHook (well, WebHooks in general) is a callback that 3rd party systems use to do something
with it. My CodeBuild project uses that WebHook and builds the project. Depending on where I commit and push
(development
or master
branch), I get the same WebHook on both CodeBuild project (again, one for development, one
for “production”), and see on which branch it was on. In the end, CodeBuild builds the project using hugo --verbose
command (--verbose
because of CloudWatch Logs) and uploads content of public
directory to S3. CloudFront is hooked up
to the S3 to deliver the content.
With CloudWatch Event, it just builds the project at specific time. Build is required since Hugo doesn’t build future posts.
Writing Scheduled Posts
If you can’t see your post, since it’s scheduled in the future, Hugo provides you with an option to build those posts:
hugo server -D --buildFuture
The --buildFuture
will build posts that are scheduled so you can see them while writing.
Expiry
Besides publishDate
front matter, Hugo also has expiryDate
:
the datetime at which the content should no longer be published by Hugo; expired content will not be rendered unless the
--buildExpired
flag is passed to thehugo
command.
You can use the same principles for schedule, and for local development. For schedule, you can set up only one specific
date on CloudWatch that is the same as expiryDate
. When writing, you can use:
hugo server -D --buildFuture --buildExpired