We recently moved several of our projects to the new Google Cloud Build for building container images and pushing them to the repository. It’s a pretty simple system (not a full CI) but it does the job well, and I liked having the “build” part separate from the “run tests” part of the toolchain. That said, I feel like this is among the many tools that leave me writing bash scripts in YAML.
Google’s new Cloud Build service works on a very simple premise: In each step choose a container image and run a command from the image. This means you could effectively do anything with it, but the simplest use case is to build docker images and push them to Google Container Repository. The repo-push step is part of the build system — it assumes that container image are an artifact of your build.
We had some projects building images in CI and other projects building images through script with manual triggers. To speed up deployments, I wanted to move all our projects to build docker images whenever the CI approved a push to
master. We accomplished this with the following steps:
- Any push to any branch in GitHub kicks off a test run in Circle CI
- If the test run passes and the branch is
master, then Circle CI pushes a tag to the repository in GitHub (e.g. “v1”, “v2”, … from the CI build number)
- Google Cloud Build is configured to look for a change to the repository tags (by syncing the code base with GitHub) and trigger a build when a
v\d+tag is added
Once builds are complete and pushed to GCR, we manually kick off deployment. This is a manual step because (1) we have manual QA on production with each release and want deployments timed so we can run through that and (2) we’re a small team so sometimes we build code across multiple services that need to be deployed in concert.
As I mentioned in the opening, I like the idea of separating the “build container images” separate from “run the test suite”. So far (two months in) it’s worked out really well for us. The cost of the builds in Google Cloud Build is really low and the performance is much faster than the build we were doing on Circle CI.
The only complaint I have about GCB is that the process is “run a command with a container image” and the way to configure that with a YAML file. So you end up getting things like this:
- name: gcr.io/cloud-builders/docker args: - build - --label - git-ref=$SHORT_SHA - -f - Dockerfile - --cache-from - us.gcr.io/$PROJECT_ID/$_APP:latest - -t - us.gcr.io/$PROJECT_ID/$_APP:$TAG_NAME - -t - us.gcr.io/$PROJECT_ID/$_APP:latest
It feels like I do this a lot these days between Kubernetes and GCB and other Google service — write scripts in YAML. It’s really not a great way to write scripts and it’s a super hard way to read them. That would be much easier to read as a shell script.