How to setup a Gatsby site on AWS using GitHub Actions - Part 3: Continuous Deployment with GitHub Actions
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 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
Review Policy
- Click the
-
On the Review policy screen:
- 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
- Summary: This should show that CloudFront has limited 'Write' access and that S3 has limited 'List', 'Read' and 'Write' access - perfect!
- Name: Enter a name for the new policy, something like
- Click
Users
in the left hand menu - Click
Add User
-
On the Add User screen
- User name: enter
GatsbyDeploy
- Access type: select
Programmatic access
- Click
Next: Permissions
- 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: Tags
- Select
-
On the Add tags screen:
- If you're a tags user then you should add a tag, otherwise it's fine to leave this blank.
- Click
Next: Review
-
On the Review screen:
- Have a quick check to see if everything looks ok.
- Click
Create user
-
On the Success screen:
- Click
Show
on the Secret access key -
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
- Click
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
-
Click
Add a new 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
Add a new secret
to add a second secret:- Name: enter
AWS_SECRET_ACCESS_KEY
- Value: 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:
name: Deploy on: push: branches: - master jobs: deploy: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v2 - name: Use Node.js 12 uses: actions/setup-node@v1 with: node-version: 12.x - name: Cache node modules uses: actions/cache@v1 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} restore-keys: ${{ runner.os }}-node- - name: Build run: | npm ci npm run build - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v1 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@v1 with: dest-s3-bucket: YOUR_BUCKET_NAME cloudfront-id-to-invalidate: YOUR_CLOUDFRONT_ID
You'll need to substitute the following values into the above:
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
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. - Commit this new file into master and it push up to GitHub (it's fine to do this as part of a Pull Request workflow). 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 master branch on GitHub. Most steps should be straightforward but there's a couple which may need some further explanation:
- Cache node modules - actions/cache@v1: this caches the node_modules directory between builds. Note it's only cached for a week so you'll need to be building reasonably frequently to see any benefit from this. See the GitHub Actions caching documentation for further details.
-
Deploy - jonelantha/gatsby-s3-action@v1: 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!