A GitHub Actions workflow to deploy to Google Cloud using the Serverless Framework

How to set up continuous deployment while keeping your Google Cloud credentials secure

I've written about the Serverless Framework before, and how it plays very nicely with AWS. With Google Cloud, I've found things are a bit trickier, and there's less documentation, probably because it's relatively new. But fear not! Here's a complete step by step to set up a GitHub workflow to deploy to Google Cloud using the Serverless Framework. The process shouldn't be too different if you are using another CI provider.

If you haven't, set up a starter project:

serverless create --template google-nodejs

First, you'll need Google Cloud system credentials. The Serverless framework has a complete guide on how to set up a service account with the right roles.

By now you should have downloaded a JSON file with your credentials, and added its path in your serverless.yml. But this path can be different if you deploy from your machine, or a fellow developer deploys from theirs, or if it's deployed via CI, right? So we want this to be an environment variable. Your complete serverless.yml file should look something like this:

Now, from your machine you can easily deploy passing the correct path:

CREDENTIALS_PATH=~/path/to/your/keyfile.json serverless deploy

Now we are ready to create our deploy workflow! We'll be using the official Serverless action. In the example workflow, they show how to pass secrets as environment variables, but as we've seen with Google Cloud we need to pass a whole JSON file. And we know it's not a good idea to commit sensitive information, so we'll need to commit an encrypted version of it, and add a script to decrypt it on deploy time. That might sound complicated but don't worry, we'll do it! 💪The GitHub Actions documentation includes a guide on how to do that, but we'll go step by step here too.

You'll need to enter a passphrase. Make sure to keep it somewhere safe as we'll need it to decrypt the file. Commit the encrypted keyfile.json.gpg file to your repository.

Create a shell script to decrypt the password. We need to use the $GITHUB_WORKSPACE path instead of $HOME (as the documentation example) because the Serverless action runs in a docker container and is not able to access any directory, just the workspace.

Save this file in .github/scripts/decrypt_secret.sh, make sure it is executable by running chmod +x decrypt_secret.sh, and commit it.

In your GitHub repository settings, add a new SECRET_PASSPHRASE secret with the passphrase you used when encrypting the file.

Now we are ready to decrypt the keyfile in our workflow, and pass its path to the Serverless action as an environment variable (inside the container the $GITHUB_WORKSPACE path is accessible via /github/workspace/ ). Here's the complete workflow file: