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
- In the AWS console go to the IAM section
- Click
Policies
in the left hand menu - Click
Create Policy
- 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": [ "s3:PutObject", "s3:GetObject", "s3:DeleteObject" ], "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 formarn:aws:cloudfront::############:distribution/##############
- Click
Next
- Click the
- 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
- Policy Name: Enter a name for the new policy, something like
- Back on the IAM dashboard, click
Users
in the left hand menu - Click
Create User
- On the User details screen
- User name: enter
GatsbyDeploy
- Click
Next
- User name: enter
- 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
- Select
- On the Review and create screen
- Click
Create user
- Click
- Back on the Users list screen:
- Click on the name of the user you just created
- On the user details screen:
- Click the Security credentials tab
- Scroll down to Access keys and click
Create access key
- Click
Other
- Click
Next
- On the Set description tag screem
- Click
Create access key
- Click
- 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.
- Login to GitHub and go to the repo for your Gatsby project
- Click the
Settings
tab - In the left hand menu click
Secrets and variables
and thenActions
- 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
- Name: enter
- 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
- Name: enter
- 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
- In the root of your folder create a
.github
directory (if it's not already there) - Inside the .github directory create a
workflows
directory. - 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) - Inside the new file paste in the following:
You'll need to substitute the following values into the above:
name: Deploy on: push: branches: - main jobs: deploy: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Use Node.js uses: actions/setup-node@v4 with: node-version: 20 - name: Build run: | npm ci npm run build - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v4 with: 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 with: dest-s3-bucket: YOUR_BUCKET_NAME cloudfront-id-to-invalidate: YOUR_CLOUDFRONT_ID
- Make sure the name of your main branch is correct - it will be
main
for newer repos andmaster
for older repos YOUR_BUCKET_NAME
: just the S3 bucket name, not the full ARNYOUR_CLOUDFRONT_ID
: the 14 character CloudFront ID (exampleE1FFE74E8RVG6W
). See Part 1 for details where to find thisYOUR_AWS_REGION
: your region, for exampleeu-west-2
${{ secrets.SECRET_NAME }}
syntax to the workfile file in the appropriate locations. - Make sure the name of your main branch is correct - it will be
- 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.
- 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!
- 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:
- Setup a nice domain name for your site. See the AWS Guide about using your own domain name
- If you plan to use Gatsby redirects then you may want to install one of the following plugins which will create the relevant redirect files as part of the site build.
That's it! Thanks for reading and good luck with your new Gatsby site!