GitHub Actions

How we automatically deploy to AWS Lightsail/EC2 Instance

Continuous Deployment, DevOps, Github Actions, AWS Lightsail, AWS EC2, Bash, Linux Screen

Posted by Richard Ryu on April, 2022

Background & Highlights

  • As a part time project, I've been helping out my friends build an online community for automobile owners on momo
  • The website was hosted and deployed via AWS Lightsail services and codebase was maintained in GitHub
  • Whenever the dev team wanted to update and deploy the latest code changes for the website, the dev team had to manually run a deployment script after ssh-ing into the Lightsail instance
  • Above process was cumbersome and the team wanted to automate the deployment process
  • In order to solve the team's pain point and provide some form of continuous deployment, I looked into Github Actions
  • Rather than create a brand new Github Actions yaml workflow file, I took advantage of existing workflows in the Github Actions Marketplace and ended up choosing appleboy's ssh for github actions
  • Despite some documentation and tutorials being available on the web, succesful execution of workflow was hard to achieve due to constant errors about private key format
  • After digging through the issues log of Appleboy's ssh for github actions, I discovered that we had to use Ed25519 ssh-key instead of RSA keys

Instructions

  1. From your AWS Lightsail console, use browser-based ssh to access your Lightsail instance
  2. Enter ssh-keygen -t ed25519 -C "your@email.com" in order to generate a public key id_ed25519.pub and a private key id_ed25519
  3. Enter cat ~/.ssh/id_ed25519 in order to print the content of the key
  4. Go to Github Settings > Secrets > Actions and then click on "New repository secret" button
  5. Copy the content of the printed id_ed25519 key from the Lightsail instance and paste it into the "Value" field of New secret
  6. Go back to the Lightsail instance and enter cat ~/.ssh/id_ed25519.pub in order to print the content of the public key
  7. Copy the printed public key and then save it under your new authorized keys list by entering nano ~/.ssh/authorized_keys2
  8. In order to provide sufficient privileges for your keys, enter chmod 700 ~/.ssh
  9. In order to provide sufficient privileges for your authorized keys, enter chmod 640 ~/.ssh/authorized_keys2
  10. Come back to GitHub and press the "Actions" tab
  11. Create a new workflow yaml file by clicking on "new workflow" > "set up a workflow yourself"
  12. Refer to GitHub Actions Documentation and the actual workflow file below that was used for our case
                          
name: Workflow Name

# Controls when the workflow will run
on:
  # Triggers the workflow on push or pull request events but only for the main branch
  push:
    branches: [ main ]

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "SSH"
  SSH:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v2

      # Runs a single command using the runners shell
      - name: Run deployment scripts on AWS Lightsail
        uses: appleboy/ssh-action@master
        with:
            key: ${{ secrets.AWS_ED25519 }}
            host: ${{ secrets.HOSTNAME_PROD_PUB }}
            username: ${{ secrets.USER_NAME}}
            script: |
              whoami
              "enter script"
                            
                          

  • For host: ${{ secrets.HOSTNAME_PROD_PUB }}, enter/save the public IP of your Lightsail instance in your repository's GitHub Secrets
  • For username: ${{ secrets.USER_NAME }} enter/save the username of the Lightsail instance.