Personal Blog (
Blog // Deploy an 11ty Static Website to AWS with GitHub Actions

Deploy an 11ty Static Website to AWS with GitHub Actions

Created: February 19, 2024 | Updated: March 21, 2024

cover image

Currently I'm using the powerful static website generator Eleventy (11ty) for this website without any server-side operation, however, the workflow of updating the website, publishing post/projects is cumbersome, as it requires for me to build the website locally and upload files manually every time I make a change.

Thus I decided to find a way to automate the process, in this post I'm going to explain how I did it.

The workflow uses a custom GitHub actions command to build the website on ubuntu and transfers files to an S3 bucket whenever the GitHub repo is updated and is based on this method by Monica.

Eleventy setup

11ty is "zero-config" by default which means that it will process all the files in the root directory, run a build process, and output resulting files to a _site directory. I made some changes in the 11ty folder structure, by creating a src folder as the input directory and a public folder as the output directory. At the end my folder structure looks like this:

root_folder/
  |-- src/
  |-- public/
  |-.eleventy.js
  |-.gitignore
  |-package.json

I also created a .gitignore file in the root directory with the following contents:

/public
node_modules

S3 Setup

AWS S3 is great for storing files. It’s cheap, fast and reliable. What you may not know is that you can also host static websites on this platform.

Hosting a static webpage is ridiculously cheap. S3 has a pay-as-you-use system. Even with a lot of users visiting your website you don’t pay much, it can serve 100.000 users just under 1 dollar. You can read the official documentation here.

After following the documentation, your static website should be available at:

your-bucket.s3-website.eu-central-1.amazonaws.com

If you want to use your own domain name as I do, you can follow this guide and use route 53 as your dns service.

Creating a policy

First, we have to create a policy that will only allow certain permissions, to create the policy I followed Monica's guide, here's the .json file that is customized to work with my website:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:ListBucket",
                "s3:DeleteObject",
                "s3:GetBucketLocation"
            ],
            "Resource": [
                "arn:aws:s3:::BUCKET-NAME",
                "arn:aws:s3:::BUCKET-NAME/*"
            ]
        }
    ]
}

Assign policy to user

I created a user with programmatic access on the AWS console from Access Management -> Users -> Add user and selected “Programmatic access” in the “Access Type” section. Next I assigned the policy that I've created to the user by clicking on the “Attach existing policies directly” box in the “Set permissions” section.

Now we have our user with programmatic access, but we need the user’s AWS credentials to give access from Github. To get the credentials visit the "Security Credentials" tab and copy the Access Key ID and Secret

GitHub Setup

I added the AWS credentials as Repository Secrets in the repo, and configured a GitHub actions workflow like this:

name: Build and Deploy to S3
on: [push]
jobs:
  build_and_deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Install dependencies
        run: npm ci

      - name: Build the website
        run: npx @11ty/eleventy
      
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: $
          aws-secret-access-key: $
          aws-region: eu-central-1 # replace this with your aws-region

      - name: Upload files to S3 with AWS CLI
        run: |
          aws s3 sync public/ s3://$ --delete 

📝NOTE
The aws s3 sync command copies files from the public directory to the S3 bucket and the --delete option will delete every file that is not in that directory, If you want to keep files/folders in your s3 bucket separate from your 11ty build do not use this method.

Running the workflow

The Workflow

Now every time when a commit is pushed to the repo the workflow will run, it will build the 11ty website and upload the results to your s3 bucket replacing the previous files.

Comments