This article will show you how to automate the deployment of your hugo site to your S3 bucket.

1- Create a new repository on Gitlab

I choose Gitlab because of Its CI/CD features. Use your gitlab account and create a new project. You can named the project as your domain name.

Once you have created your project on Gitlab, you can add the git support into your local project :

Some hints :

$ cd my-blog
$ git init
$ git remote add origin https://gitlab.com/ACCOUNT/my-blog
$ git push origin

2- Create a new IAM account for S3 deployment

First we have to create a new policy for writing into the bucket:

Create the file my-blog-bucket-write-policy.json and put the following content:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:DeleteObjectVersion",
                "s3:RestoreObject",
                "s3:ListBucket",
                "s3:GetBucketAcl",
                "s3:GetBucketPolicy",
                "s3:PutObject",
                "s3:GetObjectAcl",
                "s3:GetObject",
                "s3:AbortMultipartUpload",
                "s3:PutObjectVersionAcl",
                "s3:GetBucketCORS",
                "s3:GetObjectVersionAcl",
                "s3:DeleteObject",
                "s3:PutObjectAcl",
                "s3:GetObjectVersion"
            ],
            "Resource": [
                "arn:aws:s3:::www.my-blog.com",
                "arn:aws:s3:::www.my-blog.com/*"
            ]
        }
    ]
}

And create the policy from the JSON file.

$ aws iam create-policy --policy-name my-blog-bucket-write-policy --policy-document file://my-blog-bucket-write-policy.json

Keep the ARN of the new policy:

 1{
 2    "Policy": {
 3        "PolicyName": "my-blog-bucket-write-policy",
 4        "CreateDate": "2015-06-01T19:31:18.620Z",
 5        "AttachmentCount": 0,
 6        "IsAttachable": true,
 7        "PolicyId": "ZXR6A36LTYANPAI7NJ5UV",
 8        "DefaultVersionId": "v1",
 9        "Path": "/",
10        "Arn": "arn:aws:iam::0123456789012:policy/my-blog-bucket-write-policy",
11        "UpdateDate": "2015-06-01T19:31:18.620Z"
12    }
13}

We create the IAM account “gitlab” :

$ aws iam create-user gitlab

Attach the policy to user Gitlab:

$ aws iam attach-user-policy --user-name gitlab --policy-arn arn:aws:iam::0123456789012:policy/my-blog-bucket-write-policy

And then create an access key for user Gitlab:

$ aws iam create-access-key --user-name gitlab

Keep the access and secret keys :

1{
2    "AccessKey": {
3        "UserName": "gitlab",
4        "Status": "Active",
5        "CreateDate": "2015-03-09T18:39:23.411Z",
6        "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYzEXAMPLEKEY",
7        "AccessKeyId": "AKIAIOSFODNN7EXAMPLE"
8    }
9}

3- Enable the CI/CI support

To upload our site to the bucket we have to store the AWS access & secret keys of our user “gitlab”.

Go to Settings > CI/CD > Variables, and add at least the AWS_* variables:

The deployment flow is composed of 2 stages:

  1. build
  2. deploy

Add the file .gitlab-ci.yml and put the following content :

 1before_script:
 2  - apt-get update -yq && apt-get upgrade -y 
 3
 4stages:
 5  - build
 6  - deploy
 7
 8build:
 9  stage: build
10  script:
11    - apt-get install -yq --no-install-recommends libstdc++6 python-pygments git ca-certificates asciidoc curl gettext
12    - curl -sL -o /tmp/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/${HUGO_BINARY}
13    - dpkg -i /tmp/hugo.deb && rm /tmp/hugo.deb
14    - envsubst < config.toml.tpl > config.toml
15    - hugo --minify --enableGitInfo
16  artifacts:
17    paths:
18      - public/
19
20deploy_to_bucket:
21  stage: deploy
22  script: 
23    - gem install dpl
24    - dpl --skip_cleanup --provider=s3 --bucket=$S3_BUCKET --region=$AWS_REGION --local-dir=public/
25  only:
26    - master

To deploy the site I use dpl, but you can replace it with aws cli and the command sync.

Now push .gitlab-ci.yml to enable the CI/CD. To follow the execution of pipeline go to CI/CD > Pipelines