Deploying a Gatsby site to Azure Storage via GitHub
GitHub has become a very powerful code repository and one aspect that makes it so powerful are it's CI/CD capabilities. Let's say you have a great little Gatsby site and want to host it in Azure Storage. In a matter of minutes, you can have your repo automatically build upon check-in to your master branch and push out to your Azure Storage account. Here's how to do it.
AZURE SETUP
- Create a Storage Account
- Go to the Static Website blade and Enable the storage account's static website capabilities.
- Optionally, create a CDN on the $web container of the storage account, which is where your static site will live.
- Optionally, setup a custom domain for your CDN.
- Now you'll need to gather a bunch of variables from your Azure instance. We'll be using these soon when we create the GitHub workflow. Here they are:
- AZURE_CDN_ENDPOINT
- AZURE_CDN_PROFILE_NAME
- AZURE_CREDENTIALS
- AZURE_RESOURCE_GROUP
- AZURE_STORAGE_CONNECTION_STRING
- AZURE_SUBSCRIPTION_ID
GITHUB
In our GitHub repository, there are 2 areas that we'll be working with, Secrets and Actions.
Secrets
Secrets are GitHub's area to store variables that contain important data. You can get to the Secrets area by going to the repo's Settings page and then selecting the Secrets link in the left navigation. On that page, you will enter the Azure variables you grabbed from the previous step.
Actions
Actions are where you can define and monitor your CI/CD pipelines. They are created by creating yaml scripts. Yaml is capable of many things. Today, I'm just showing how to build a Gatsby site, deploy it to Azure Storage and clear the CDN cache.
We only want to deploy when code is checked into the master branch. If you want the trigger to occur on a different branch, just substitute the name of your branch.
on:
push:
branches:
- master
Now we're going to create a workflow with 2-steps. Our script requires the use of an ubuntu image to run on with Node js (version 15) installed.
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [15.x]
Next, we're going to tell the script to use Node.js and install the Gatsby cli. Once that is installed, we will do a simple build using the gatsby-cli.
- uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies
run: |
npm install
npm install -g gatsby-cli
- name: Build with Gatsby
run: gatsby build
Once the site is built, we can now push it out to Azure using the azure-cli. These next 2 lines first delete every file from teh $web container and then upload the new files
- name: Azure upload
uses: azure/CLI@v1
with:
azcliversion: 2.0.72
inlineScript: |
az storage blob delete-batch -s "\$web" --connection-string "${{ secrets.AZURE_STORAGE_CONNECTION_STRING }}"
az storage blob upload-batch -d "\$web" -s public --connection-string "${{ secrets.AZURE_STORAGE_CONNECTION_STRING }}"
Now if you're using an Azure CDN to front the site, you should purge the cache or else it could take a long time for the site to reflect the changes. We do that with a purge job. As you can see below, it's waiting until the build job finishes first, then it logs into Azure, purges the CDN and logs out. Note all the Secrets variables that are used through the script.
purge:
needs: build
runs-on: ubuntu-latest
steps:
- name: Azure service principal login
uses: Azure/[email protected]
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Purge CDN
run:
az cdn endpoint purge -g ${{ secrets.AZURE_RESOURCE_GROUP }} -n ${{ secrets.AZURE_CDN_ENDPOINT }} --profile-name ${{ secrets.AZURE_CDN_PROFILE_NAME }} --subscription ${{ secrets.AZURE_SUBSCRIPTION_ID }} --content-paths "/\*" --no-wait
- name: Azure service principal logout
run: |
az logout
Here's the entire yaml script in its entirety.
name: Deploy Gatsby to Azure Storage
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [15.x]
steps:
- uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies
run: |
npm install
npm install -g gatsby-cli
- name: Build with Gatsby
run: gatsby build
- name: Azure upload
uses: azure/CLI@v1
with:
azcliversion: 2.0.72
inlineScript: |
az storage blob delete-batch -s "\$web" --connection-string "${{ secrets.AZURE_STORAGE_CONNECTION_STRING }}"
az storage blob upload-batch -d "\$web" -s public --connection-string "${{ secrets.AZURE_STORAGE_CONNECTION_STRING }}"
purge:
needs: build
runs-on: ubuntu-latest
steps:
- name: Azure service principal login
uses: Azure/[email protected]
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Purge CDN
run:
az cdn endpoint purge -g ${{ secrets.AZURE_RESOURCE_GROUP }} -n ${{ secrets.AZURE_CDN_ENDPOINT }} --profile-name ${{ secrets.AZURE_CDN_PROFILE_NAME }} --subscription ${{ secrets.AZURE_SUBSCRIPTION_ID }} --content-paths "/\*" --no-wait
- name: Azure service principal logout
run: |
az logout
Try to check in some code to the master branch and watch the new workflow work. This is just one possibility of what GitHub Actions can do. If this isn't exactly what you're looking for, hopefully it'll get you part of the way.