S3 Logo


When it comes to our website maintenance our previous playbook followed a traditional but dated model:

  • edit page
  • package new website
  • save website to git repository
  • upload to vps / transfer to AWS S3

This model was time consuming, restricted development to a workstation where we could ruby to package the website (because we favour Jekyll, but you may prefere Hugo).
We wanted to change this model and use modern DevOps practises, so we started playing with Gitlab which is known for its CI functions, to automatically compile and upload our website modifications automatically to AWS S3.


Jekyll is a static website builder. Static websites are great for marketing and blogging platforms, and usually more secure than their dynamic conterparts.
Having a static website also has its advantages that we can run a website at a very competetive and affordable rate on AWS S3, with CDN support from Cloudfront. Running a website on S3 costs very little compared to complicated EC2 setups, and Cloudfront CDN removes any need or worry of scaling the website within AWS VPCs.

Jekyll is opensource and has a large group of followers meaning the are freely available skins or themes, so its very easy to create new content or projects. For themes we recommend the following sites:


Create an S3 Bucket

If you havnt already created a Bucket, this is how you do it.

Simply log into AWS navigate to S3 and create a public bucket.

  1. In properties activate static webhosting
  2. In permissions, head to bucket policy
  3. copy the following Policy.json, but remember to change the bucket name to reflect your bucket.
    "Version": "2012-10-17",
    "Statement": [
            "Sid": "PublicReadForGetBucketObjects",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::<bucket name>/*"

Tip: We like to create buckets as www..com and store the files here, then create a second bucket .com, and second bucket we enable static web hosting, but this time configure a redirect to our www..com address.

Create Cloudfront CDN

Creating a distribution is as easy as:

  1. Create a Distribution
  2. Web
  3. Then configure the CDN to use your domain, and point it to your S3 bucket

There are many different configuration options here, we will skip the details. But you should be able to set up the CDN to your specific needs with ease, and configure TLS and use the SSL certificates from AWS Certificate Manager.

Create a new user

We want to create a new user with restricted privileges to manage the upload of our website to S3 and edit Cloudfront.
Simply log into AWS navigate to IAM and create a new user, when it comes to policies use the following poilcy.json but dont forget to change the variables to reflect your setup:

    "Version": "2012-10-17",
    "Statement": [
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
            "Resource": [
                "arn:aws:s3:::<S3 Bucket name>/*",
                "arn:aws:cloudfront::<accountnumber>:distribution/<distribution ID>"
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "s3:ListBucket",
            "Resource": "*"

Gitlab CI

Navigate to your Git repository, goto:

  1. Settings
  2. CI/CD
  3. Variables

Next fill in these variables:


Next Navigate to

  1. Runners

Setup at least one runner. You may need to visit the gitlab documentation here for specific instructions for your system, if your using the public www.gitlab.com you do not need to worry about runners as they are already pre-configured.


Important the extension should be .yml otherwise things will get a lot harder.

This file holds all the instructions to test, build and deploy our website from Docker images. Here is our .gitlab-ci.yml

image: ruby:2.7

  - build
  - deploy

  stage: build
    - bundle config set path 'vendor/cache'
    - bundle install
    - bundle exec jekyll build --future
      - _site
  when: always
    - master

  stage: deploy
  image: python:latest
    - pip install awscli
    - aws s3 sync --delete _site/ s3://${S3_BUCKET}
    - aws cloudfront create-invalidation --distribution-id ${CLOUDFRONT_DISTRIBUTION_ID} --paths '/*'
      - _site
  when: always
    - master

Now we can make changes to our website from any device (using the gitlab http interface)! After we commit changes, we can use the AutoDevOps to automatically build and deploy our website to S3, or manually trigger the process by running a pipeline.

Share on: