Painless CI CD with Hugo and Lambda

I’ve built my blog with Hugo - and I’ve been loving it so far!

Hugo is a static website generator written in Go, it’s blazing fast and super easy to use.

I’ve put the source of my blog on GitHub. Normally you would need to download Hugo and run it locally, and then sync the output to a webserver.

I’ve written a Lambda script that does this for you, and more - such as:

This allows me to write blog posts anywhere I can run Git, it also gives me a nice history by virtue of Git commit history



SNS Configuration

In order for GitHub to send you a notification when there is a commit you will need to setup SNS

Create an API Key

GitHub will need credentials to publish to your SNS topic

GitHub Webhook

From GitHubs documentation

To set up a repository webhook on GitHub, head over to the Settings page of your repository, and click on Webhooks & services. After that, click on Add webhook.

You’ll need to provide the IAM credentials that you previously created.

Create a IAM role

Your Lambda function will need permissions to sync to S3, in order to do so head over to the IAM Console

create a role policy called s3_blog_upload and attach a policy that is similiar to the following

    "Version": "2012-10-17",
    "Statement": [
            "Effect": "Allow",
            "Action": [
            "Resource": "arn:aws:s3:::BUCKETNAME/*"
            "Effect": "Allow",
            "Action": [
            "Resource": "arn:aws:logs:::*"

Note: the logs actions are optional. Include them if you want the output of the Lambda function to be returned to you


Download the code from michaelmcallister/hugo-s3-lambda-sync


  "Records": [
      "EventVersion": "1.0",
      "EventSubscriptionArn": "arn:aws:sns:EXAMPLE",
      "EventSource": "aws:sns",
      "Sns": {
        "SignatureVersion": "1",
        "Timestamp": "1970-01-01T00:00:00.000Z",
        "Signature": "EXAMPLE",
        "SigningCertUrl": "EXAMPLE",
        "MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e",
        "Message": {
          "repository": {
            "name": "REPO_NAME",
            "full_name": "USER/REPO_NAME",
	    "html_url": ""

Lambda Success

comments powered by Disqus