Deploying apps in Google Cloud Platform using GitHub Actions.



After GitHub announced action last year, they recently announced that it would support CI/CD free for the public repository as well. This is exciting because earlier most of the public repos were leveraging 3rd party Travis CI.  Travis CI is really simple for straight forward use cases, sometimes just one line. And also free for open source projects (Public repos on GitHub)

I had signed up for GitHub action beta program earlier and recently got the invite. After signing up you can see the new "Actions" tab in the top of all of your repositories

The new Actions Tab

Earlier I blogged about how to deploy to google cloud from GitHub repository using Google Cloud Build. Here I wanted to use GitHub Actions instead to directly deploying a cloud function.

  • To get started one needs to have a .github/workflows directory at the root of the repo.
  • Under the above directory, one can have multiple .yaml files to configure multiple workflows which can be run independently.
  • The important sections of the action YAML are as follows
    • Tell when the action needs to execute. Here I want it to trigger every time I commit to master in a specific directory

      on:
      push:
      branches:
      - master
      paths:
      - 'functions/getQuotesByDate/*'
       
    • Now define the build steps

      steps:
      - uses: actions/checkout@v1
      - name: Install gcloud SDK
      run: |
      sudo apt-get update && sudo apt-get install google-cloud-sdk
      - name: Activate Service Account
      env:
      GCLOUD_AUTH: ${{ secrets.GCLOUD_AUTH }}
      run: |
      echo "$GCLOUD_AUTH" | base64 --decode > "$HOME"/gcloud.json
      sh -c "gcloud auth activate-service-account --key-file=$HOME/gcloud.json $*"
      - name: deploy function
      run: |
      gcloud functions deploy getQuotesByDate --runtime nodejs8 --project demoneil --service-account [email protected] --source functions/getQuotesByDate

  • Since you are deploying automatically from a CI/CD system you would need a Service Account of your GCP project which has enough permission to deploy a function. You can create a service account and key as follows.
    •  In GCP console go to IAM & Admin --> Service Accounts
    • Select your GCP project from the top list
    • Provide a conspicuous name, Id and description 
    • Provide enough permission to deploy a cloud function. An editor will work but in a real scenario, you may want to restrict it to further less e.g. GCF admin or equivalent.
    • Create a key for your Service Account.
    • Convert the key to base64 string. For example, in bash, you can run the following

      $base64 ~/Desktop/demoneil-26fabe6f9020.json

    • Since we can't really check in the key in the repo we have somehow hide it from the users. Take the above base64 string and create a GitHub secret in the Repository Settings

      GitHub Actions allow you to access this secret from work flow defination file.
      e.g. ${{ secrets.GCLOUD_AUTH }}

      Note that in the YAML file we have written command to decode the secret string back to JSON and store it in the local VM where the action is running. 
While the above method is good for demonstration, installing the Google Cloud SDK in the VM is an expensive operation which can display your deployment from the time you check-in code. To make it faster one can just use the docker container containing the SDK. More on this.

Also, ideally this whole authentication process and command line (to deploy) should be a pre-defined action like this, either in the repo itself or at a central repository. Actions are re-usable, instead of everyone is trying to run the same set of command in the YAML file.

I will probably write a follow-up post after creating a re-usable action. This is just a small example, similarly, any deployment in GCP can be done by authenticating and adding appropriate gcloud command like above.