Building a blog: Deploying using Github Actions and AWS
April 20, 2021In Building a blog with Publish we saw how to make a website using Publish. Today let's see how we can automate its deployment using Github Actions and AWS.
Github Actions
Github Actions is quite new compared to other solutions as it was made available back in... 2020 😯.
To use it all you need to do it is create Yaml files into a .github/workflows
root directory. Each one define a workflow that will be automatically executed on your repository based on some events you defined.
When starting the blog I first decided to have one workflow (deployment) handling both preproduction and production environments. While appealing at first because avoiding some code duplication you quickly end up with lots of conditions inside it making very hard to maintain.
So after some try and learn I actually decided to have 2 workflows hence 2 Yaml files:
- preproduction.yaml
- production.yaml
Events
First thing to define is events. Events are activity triggering your workflow like pull requests, pushes and so on. I decided to trigger preproduction when opening a pull request or pushing on master while production is triggered on every Tuesday or manually.
# Preprod
on:
pull_request:
branches: [master]
push:
branches: [master]
# Prod
on:
# Deployment is scheduled to be trigged on every Tuesday at 14h45 UTC
schedule:
- cron: "45 14 * * TUE"
# This allow me to manually trigger the workflow from Github interface
workflow_dispatch: {Â }
Jobs
Our Yaml next entry is jobs. You can have multiple jobs in a workflow but mines only use one: deploy
. It define two things:
- A Runner (no link with Cyberpunk 2077) to set the host machine we want to use
- The actions we want to run
For now all we need is to checkout the repository, install swift and build our project:
#Preprod
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v2
- name: Install swift
uses: YOCKOW/Action-setup-swift@v1
with:
swift-version: "5.3.3"
- name: Generate site preview
run: swift run SwiftUnwrap --upcoming-articles
#Prod
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v2
- name: Install swift
uses: YOCKOW/Action-setup-swift@v1
with:
swift-version: "5.3.3"
- name: Generate site
run: ENV=PROD swift run
We don't use a macOS runner because there's no really need for it. Beside Github Actions is limited to 2,000 mins/month on Linux and only 200 mins/month on macOS.
Deployment
Now that our workflow run and build our project we need to deploy it. You get multiple choices to deploy your website: AWS, Scaleway, Heroku,... and Netlify.
I did test Netlify but ended up with AWS for two reasons:
- Configuration is very limited and the whole thing felt too much "magic" to me
- Previous deployments are not deleted. Meaning deploying 300 times would result in having 300 times my project on servers. It might seem ridiculous to some but to me it is a very negative ecological aspect 🌳🌎.
Netlify being a NoGo I went to use AWS buckets.
AWS
You'll first need to create a AWS S3 bucket on Amazon and configure it for being accessible as a website.
Once done we then need to add a step in our Github Workflow to deploy our built website on AWS. Github Actions already come with AWS CLI installed so we won't need extra step to download those.
# Preprod
- name: Deploy to Preprod
run: |
aws s3 sync Output $AWS_S3_URI --delete
aws s3 cp robot.txt $AWS_S3_URI
env:
AWS_S3_URI: ${{ secrets.AWS_S3_URI_PREPROD }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
# Prod
- name: Deploy to Prod
run: aws s3 sync Output $AWS_S3_URI --delete
env:
AWS_S3_URI: ${{ secrets.AWS_S3_URI_PROD }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
If your deployment fail and you have 'botocore.utils.BadIMDSRequestError' error, change your runner to ubuntu-18.04.
You should now have a running blog on the web. Congratulations! 🎉