A GitHub Actions workflow to deploy to Google Cloud using the Serverless Framework
Tags: serverless, githubactions
Published: 2020-02-06 07:52:01

---
title: A GitHub Actions workflow to deploy to Google Cloud using the Serverless Framework
published: true
date: 2020-02-05 17:00:00 UTC
tags: serverless, github actions
canonical_url: https://www.codegram.com/blog/a-github-actions-workflow-to-deploy-to-google-cloud-using-serverless-framework/
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/39dlzfjdkg144wlsofgj.jpg
---

I've [written about the Serverless Framework](https://www.codegram.com/blog/serverless-for-front-end-developers) 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](https://serverless.com/framework/docs/providers/google/guide/credentials/) 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](https://serverless.com/framework/docs/providers/aws/guide/variables/#referencing-environment-variables). Your complete `serverless.yml` file should look something like this:

```
    service: my-project

    provider:
      name: google
      stage: dev
      runtime: nodejs8
      region: europe-west1
      project: my-project
      credentials: ${env:CREDENTIALS_PATH}

    plugins:
      - serverless-google-cloudfunctions

    package:
      exclude:
        - node_modules/**
        - .gitignore
        - .git/**

    functions:
      first:
        handler: http
        events:
          - http: path

```

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](https://github.com/serverless/github-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](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets#limits-for-secrets) on how to do that, but we'll go step by step here too.

First, encrypt the file (with Mac I installed [GPG Tools](https://gpgtools.org/))

```
    $ gpg --symmetric --cipher-algo AES256 keyfile.json
```

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.

```
    #!/bin/sh

    # Decrypt the file
    mkdir $GITHUB_WORKSPACE/secrets
    # --batch to prevent interactive command --yes to assume "yes" for questions
    gpg --quiet --batch --yes --decrypt --passphrase="$SECRET_PASSPHRASE" \
    --output $GITHUB_WORKSPACE/secrets/keyfile.json keyfile.json.gpg

```

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:

```
    name: Deploy

    on:
      push:
        branches:
          - master

    jobs:
      deploy:
        name: deploy
        runs-on: ubuntu-latest
        steps:
        - uses: actions/checkout@master
        - name: npm install
          run: npm install
        - name: Decrypt secret
          run: ./.github/scripts/decrypt_secret.sh
          env:
            SECRET_PASSPHRASE: ${{ secrets.SECRET_PASSPHRASE }}
        - name: serverless deploy
          uses: serverless/github-action@master
          with:
            args: deploy
          env:
            SERVERLESS_ACCESS_KEY: ${{ secrets.SERVERLESS_ACCESS_KEY }}
            CREDENTIALS_PATH: /github/workspace/secrets/keyfile.json

```

Finally, your project is set up for continuous deployment! You can find the whole code in [this repository](https://github.com/codegram/google-serverless-deploy).

Of course, you should also have workflows to run tests or lint your code. At Codegram we love GitHub Actions, and we have a repo with [useful workflows](https://github.com/codegram/useful-github-workflows). Make sure to take a look!

* * *

Cover photo by [Daniel Mayovskiy](https://unsplash.com/@godje?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)