Stacks on Stacks

Customizing Cloud Build Notifications

Recently, I’ve started leveraging Cloud Build for building and testing Docker images as part of a CI/CD pipeline. In this post, I’ll briefly cover a few of the benefits of using Cloud Build, how to get it set up for sending slack notifications, and how to customize the slack notifications.

Benefits of Cloud Build

Fully Managed Service

The first big benefit I like about Cloud Build is that it is a fully managed service. This means I don’t have to spend time installing it or configuring build machins for it, although if you want to build projects on a private network, it appears there is an alpha feature that allows you to do just that. The fact that it is so low touch means that you can have Cloud Build integrated with GitHub and running builds in about an hour.

Ability for local builds

The gcloud command line tools have a way to submit remote builds, but more impressively, you can run the build locally first which helps decrease feedback time and leads to faster testing cycles:

cloud-build-local --config=cloudbuild.yaml --dryrun=false .

Low Cost

Currently, Cloud Build offers 120 build minutes free per day. After that, the cost per minute on the small instances is very reasonable for not having to manage any infrastructure and only paying for what you use. Even when we used the larger machines for a while for quicker builds, the cost was quite low(~ $5/month). This also should save money compared to our EC2 spot instances with Jenkins since those take a while to disappear after doing a build and we are still paying for that time.

Quick Start Times

One thing I dislike about our Jenkins instance is that it takes a while to provision a spot EC2 instance and for that instance to become useable. With Cloud Build, the instances are either pre-warmed or have been optimized to start very quickly. I enjoy being able to push a commit to GitHub and being able to watch the build start almost immediately.

Easy Configuration

Setting up Cloud Build to be triggered from GitHub is very easy and only takes a few clicks. The integration with GitHub is really nice and the triggers are quite customizeable for different tags or branches.

The syntax for Cloud Build is fairly straight forward. Personally, I wish it was a little bit closer to Travis CI’s format and functionality, but its still quite nice. It feels very tailored to developers with a knowledge of Docker and provides features like timeouts, parallel execution, and variable substitution. One of my favorite features it the ease with which you can use secrets either by encrypting files or using ecrypted environment variables. This allows for things like storing credentials for private docker regestries and authentication for pulling or pushing images if you happen to not be using gcr.io or are using multiple registries.

Isolation

One issue we would always run into with our Jenkins worker nodes is that sometimes some jobs would not exit cleanly and would leave some docker containers behind. Because of this, we would have to write extra error handling code to clean up those containers otherwise subsequent jobs which landed on the same instance would fail. With Cloud Build each build is run in isolation, so this is one less thing to worry about.

Setting up Slack Notifications

Google provides great documentation on how to set up a cloud function to subscribe to the cloudbuild pub/sub notifications here. At the time of writing this blog post, the example code is written for node 6, but you’ll want to use the node 8 runtime, as it looks like the node 6 runtime for cloud functions is deprecated.

You can see the below section for a gist of the code which you can deploy with:

gcloud functions deploy subscribe --stage-bucket <your-bucket>_cloudbuilds --trigger-topic cloud-builds --runtime nodejs8

Customizing the Slack Notifications

The example code was great for getting us up and running, but we wanted a little more flexibiity. Mainly in which slack channel we sent the notification to as well as which statuses we would send notifications on.

The Code

In the following snippet, you can find the index.js and the package.json files which get uploaded for the cloud function which runs in response to the cloud build events. A copy of the LICENSE from https://github.com/Philmod/google-cloud-build-slack has also been included as I borrowed from Philmod’s work for this.

The cloudbuild.yaml file

Now that you have the cloud function set up, you are finally ready to add additional information to your cloudbuild.yaml file to specify which statuses and slack channel you want to notify for a particular build.

steps: []

substitutions:
  # Statuses to send webhooks messages on
  _STATUSES: "FAILURE, INTERNAL_ERROR, TIMEOUT, CANCELLED"
  # The slack webhook URL to send messages to
  _SLACK_WEBHOOK_URL: "<your webhook URL here>"

# Needed becuase the above substitution values are not used in the steps.
options:
  substitution_option: 'ALLOW_LOOSE'