GitHub Actions: Serverless on Google Cloud

Serverless computing through the Google Cloud Platform (GCP) is a great option for companies looking to host applications in the cloud without managing servers. GCP’s App Engine and Cloud Run allow apps to scale automatically in a cost-effective way.

 

App Engine was GCP’s original serverless platform, allowing autoscaling, automatic infrastructure setup like domain mapping, and supporting most of the common programming languages out of the box. Cloud Run and Cloud Functions became the more popular alternatives, as they improved upon App Engine as a more flexible option.

 

Developers can further increase this ease of use by automatically deploying updated versions via GitHub Actions in response to commits in a GitHub repository.

 

In this guide, I will explain how to set up GitHub Actions to continuously deploy an app on the Google Cloud Platform. The guide uses App Engine, as it is based on a real-life use case for a client who already had this set-up, but keep in mind that these steps can also be adapted to deploy to Cloud Run or Cloud Functions.

Setting Up GitHub Actions

This article assumes you already have a GCP and GitHub working setup and that your account has all the necessary permissions to perform the actions in the article.

 

First, add a GitHub Action Definition file to your project:

Then, give the action a name, specify the permissions, and specify the branch that the action will be triggered from.

				
					     name: Build and Deploy to App Engine

     run-name: Deploy to App Engine by @${{ github.actor }}

         on:

              push:

                     branches: [ “gcp-deploy” ]

				
			
TIP

Typically, the main branch is used as the default for smaller projects. However, if you only want releases to happen on demand, you can create a new branch with a different name, as I did for this demo, and push from the main to this branch for a new release.

 

The next step is to add job details and the checkout, auth, and deploy-appengine actions from the Actions marketplace. The GCP auth action utilizes Workload Identity Federation, an OAuth-based implementation. This allows the GitHub runner executing the workflow to perform actions on your GCP project.

Setting up authentication and required APIs

We are almost ready to test this out. However, since the workflow utilizes Workload Identity Federation (WIF) for authentication, a service account and provider will need to be configured if you don’t already have them in place. The setup can be done via the Cloud Console or using the gcloud Command Line Interface (CLI) as explained here.

 

Additionally, you’ll need to enable the App Engine Admin API, so head over to the Cloud Console -> APIs & Services -> Google App Engine Admin API and enable that.

Configuring secrets

The job configuration is managed in the Action file using environment variables and secrets, which must be configured in the repository’s Settings -> Secrets and variables -> Actions. It’s good practice to configure these keys per environment. The separate environments will need to be created if they don’t exist before defining the variables.

I chose Environment secrets for privacy reasons. Be sure to fill in the correct values for GCLOUD_PROJECT_ID, WIF_PROVIDER, and WIF_SERVICE_ACCOUNT. You should have the Identity Federation values from the initial set up of WIF, but they can also be fetched: you can use the CLI or the Cloud Console by navigating to IAM & Admin -> Workload Identity Pools and Service Accounts.

Performing a test run

Now everything is in place for trying out the workflow. Since I configured the Action to only run when there are commits on the “gcp-deploy” branch, let’s add some code that we can deploy.

 

I used the Quickstart for Node.js in the App Engine flexible environment sample code from the official Google App Engine docs available here, but you could use any existing application code.

 

Assuming you are using the node.js sample app from above, add the following to the Action file in order to have a working setup.

				
					    jobs:
       build-image-and-deploy:
          runs-on: ubuntu-latest
          environment: staging

          permissions:
              contents: ‘read’
              id-token: ‘write’
          steps:
              – name: Checkout
              uses: actions/checkout@v3

              – name: ‘Google auth’
                 id: ‘auth’
                 uses: ‘google-github-actions/auth@v1’
                 with:
                     workload_identity_provider: ‘${{ secrets.WIF_PROVIDER }}’
                     service_account: ‘${{ secrets.WIF_SERVICE_ACCOUNT }}’

              – name: ‘Deploy to App Engine’
                 id: ‘deploy’
                 uses: ‘google-github-actions/deploy-appengine@v1’
                 with:
                    project_id: ‘${{ secrets.GCLOUD_PROJECT_ID }}’
                    deliverables: app.yaml

				
			

Once that is done, just create or checkout the “gcp-deploy” branch and push some code to it. This will trigger the build and the deployment to the App Engine.

If all is well, you’ll see that the OpenID Connect integration is working through the Workload Identity Federation. WIF enabled seamless authentication between the GitHub Actions workflow and the Google Cloud service account, so we were able to run the build and deploy our service.

 

The source code for this article can be found here.

 

The advice was tested and summarised by our engineering lead from the Iasi office, Codrin Baleanu.

Published:
10 October 2023

Related white papers