jonelantha: Blog

How-To: Setup Gatsby on AWS using GitHub Actions [3/3]: Setup Continuous Deployment with GitHub Actions

4th May 2024 - (revised version of a post originally published 3rd March 2020)

This is Part 3 of a how-to guide to help you host your Gatsby site on AWS (with Continuous Deployment provided by GitHub Actions). See Part 1 and Part 2 for more information.

It's time to deploy your Gatsby Site!

We'll assume you have a Gatsby project ready to go and it's in a repo which has been pushed up to GitHub. If you've followed the previous parts of the guide you should also have an S3 bucket and CloudFront distribution waiting ready to host your site. Time to deploy!

There's two parts to setting up the deployment, first we need to create an AWS IAM user, GitHub will use this user to access S3 and CloudFront. After that we need to create the deployment workflow in GitHub - once that's done any changes pushed to the main branch (or master branch) will automatically be deployed to AWS.

Setup the IAM user

  1. In the AWS console go to the IAM section
  2. Click Policies in the left hand menu
  3. Click Create Policy
  4. On the Create Policy screen:
    • Click the JSON tab
    • Cut and paste the following:
        "Version": "2012-10-17",
        "Statement": [
                "Sid": "1",
                "Effect": "Allow",
                "Action": "s3:ListBucket",
                "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME"
                "Sid": "2",
                "Effect": "Allow",
                "Action": [
                "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*"
                "Sid": "3",
                "Effect": "Allow",
                "Action": "cloudfront:CreateInvalidation",
                "Resource": "YOUR_CLOUDFRONT_ARN"
    • In the above, replace YOUR_BUCKET_NAME with your bucket name (you should replace both occurrences but be careful to leave the /* in place after the second occurrence)
    • Replace YOUR_CLOUDFRONT_ARN with the full ARN for your CloudFront distribution. This can be found on the summary page of your CloudFront distribution (see Part 1 for details). It should have the form arn:aws:cloudfront::############:distribution/##############
    • Click Next
  5. On the Review and create screen:
    • Policy Name: Enter a name for the new policy, something like GatsbyDeployPolicy
    • Description: Enter a description if you wish but it's fine to leave this blank
    • Permissions defined in this policy: This should show that CloudFront has limited 'Write' access and that S3 has limited 'List', 'Read' and 'Write' access - perfect!
    • Click Create policy
  6. Back on the IAM dashboard, click Users in the left hand menu
  7. Click Create User
  8. On the User details screen
    • User name: enter GatsbyDeploy
    • Click Next
  9. On the Set permissions screen
    • Select Attach existing policies directly
    • In the search box enter GatsbyDeployPolicy (or whatever you named the policy above)
    • Select the checkbox on the GatsbyDeployPolicy row
    • Click Next
  10. On the Review and create screen
    • Click Create user
  11. Back on the Users list screen:
    • Click on the name of the user you just created
  12. On the user details screen:
    • Click the Security credentials tab
    • Scroll down to Access keys and click Create access key
    • Click Other
    • Click Next
  13. On the Set description tag screem
    • Click Create access key
  14. On the Retrieve access keys
    • Click Show

    • We'll need these two keys to setup the GitHub Actions deployment workflow in the next section - so keep the console open in your browser until you've setup the secrets, we'll do that at the beginning of the next section.

      These two values grant access to modify the files in your bucket - so as a security best practice you should avoid saving these values anywhere permenantly

So what did we do in this section? We created a user which has some very specific permissions set (these were defined as part of the GatsbyDeployPolicy policy). These are the very minimum privileges needed to deploy the site (this is in accordance with AWS IAM best practices to grant the least privileges to users).

Setup the GitHub Actions deployment workflow

Finally it's time to setup the GitHub Actions deployment workflow.

  1. Login to GitHub and go to the repo for your Gatsby project
  2. Click the Settings tab
  3. In the left hand menu click Secrets and variables and then Actions
  4. Click New repository secret
    • Name: enter AWS_ACCESS_KEY_ID
    • Value: paste in the Access key ID value shown in the AWS console.
    • Click Add secret
  5. Again, click New repository secret to add a second secret:
    • Name: enter AWS_SECRET_ACCESS_KEY
    • Secret: paste in the Secret access key value shown in the AWS console.
    • Again, click Add secret
  6. The secrets should now be added and there's no longer any reason to retain the two AWS access keys

Now open up your Gatsby project in your favourite IDE

  1. In the root of your folder create a .github directory (if it's not already there)
  2. Inside the .github directory create a workflows directory.
  3. Inside the workflows directory create a file called deploy.yml - it can be named anything but should end in .yml (so your new file should be located at ./.github/workflows/deploy.yml)
  4. Inside the new file paste in the following:
    name: Deploy
          - main
        runs-on: ubuntu-latest
          - name: Checkout
            uses: actions/checkout@v4
          - name: Use Node.js
            uses: actions/setup-node@v4
              node-version: 20
          - name: Build
            run: |
              npm ci
              npm run build
          - name: Configure AWS Credentials
            uses: aws-actions/configure-aws-credentials@v4
              aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
              aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
              aws-region: YOUR_AWS_REGION
          - name: Deploy
            uses: jonelantha/gatsby-s3-action@v3
              dest-s3-bucket: YOUR_BUCKET_NAME
              cloudfront-id-to-invalidate: YOUR_CLOUDFRONT_ID
    You'll need to substitute the following values into the above:
    • Make sure the name of your main branch is correct - it will be main for newer repos and master for older repos
    • YOUR_BUCKET_NAME: just the S3 bucket name, not the full ARN
    • YOUR_CLOUDFRONT_ID: the 14 character CloudFront ID (example E1FFE74E8RVG6W). See Part 1 for details where to find this
    • YOUR_AWS_REGION: your region, for example eu-west-2
    NOTE: You may prefer not to add these values to the repo, particularly if it's a public repo. Instead you can define these values as secrets and then add the ${{ secrets.SECRET_NAME }} syntax to the workfile file in the appropriate locations.
  5. Commit this new file into main and it push up to GitHub (it's fine to create a Pull Request first and then review/merge). Once merged the deployment should begin.
  6. In GitHub take a look at the Actions tab, you should be able to see the console output as your site is deployed to AWS!
  7. Once complete, in your browser navigate to your CloudFront distribution's Domain name (it's on the CloudFront Distribution summary page, see Part 1 for more details). Fingers crossed you'll see your Gatsby site, served by AWS!

So what's going on in that deploy.yml file?

GitHub Actions will execute the workflow file step by step - this happens every time any changes are pushed up to the main (or master) branch on GitHub. Most steps should be straightforward but the Deploy step may need some further explanation:

  • Deploy - jonelantha/gatsby-s3-action@v3: this is a GitHub action created by the author for the purpose of deploying a Gatsby site to AWS:

    • It copies the site files to the specified S3 bucket and then sets the cache headers according to Gatsby caching recommendations
    • It invalidates the specified CloudFront distribution - if we don't do this then Cloudfront may continue to serve up the previous version of your site.

    See the documentation if you're interested in learning more.

Next steps

Great, you did it! There's a couple of things you'll probably want to consider doing next:

That's it! Thanks for reading and good luck with your new Gatsby site!

© 2003-2024 jonelantha