Skip to content


This section of the guidebook discusses how we deploy applications to Google Cloud. It does not discuss legacy deployments.

It is intended as a guide for those new to the division or those interested in how we do things generally.

Not all deployments will use all of the techniques covered in this section but all the techniques here are embodied in at least one live service. Where possible, links to techniques being used in a live service are provided. Some of those links may be restricted to current DevOps members or members of the University.

The 10,000 foot view

Wherever possible, we attempt to automate our deployments either through GitLab CI pipelines or terraform configurations. The ideal is that one can spin up a completely parallel environment for a service with one command and that command requires the minimum amount of local setup for your machine.


Our deployments vary greatly in how well they meet this ideal. In particular, some of our older services have rough edges in their deployments. Usually these are documented in dedicated service documentation.

To help us meet this ideal, we strive that our deployments have the following characteristics:

  • They use infrastructure as code to provide a machine readable and runnable description of our deployments.
  • They are generic. We try to avoid as many hard-coded globally unique identifiers as possible by generating identifiers dynamically. This makes it easier to spin up dedicated testing or development environments.
  • They avoid clickops when possible and carefully document it when not.
  • They are consistent. We are a small team relative to the number of services we run. Keeping our deployments consistent with each other where possible makes it easier for Engineers to move between them.

Our standard environments

By keeping our deployments generic we can easily stand up parallel deployments which we term "environments". All products should have a production and staging environment. Ideally these should be as similar to each other as technology and budgets allow.

In principle standing up a new environment should be simple and quick enough that Engineers can provision their own development environment. In reality we find it is useful to keep a dedicated development environment provisioned for testing changes. This is only an optimisation; it should be a relatively straightforward and automated process to tear down the dev environment and re-build it from scratch.

Our standard deployment

We have a standard deployment boilerplate (University members only) based on terraform. Pages in this section of the guidebook will often refer to specific parts of the boilerplate to provide a concrete example of a technique.

Per-product terraform configurations are usually found in a project named "infrastructure" or, historically, "deploy" within the project-specific group in GitLab.

Where feasible we try to keep these visible to signed in University members to encourage cross-team collaboration and learning.

Deploy on day one

Through hard won experience we have learned that spending several weeks developing a product and then trying to deploy it means that it is all to easy to design in architectures which make it hard to deploy, maintain or upgrade the product.

To combat this we have a "deploy on day one" policy. When we start work on a new product we:

  • if required, bootstrap a new web application using the webapp boilerplate,
  • open a merge request in the gcp-infra project adding the new product to our Google Cloud infrastructure,
  • bootstrap a new deployment using the deployment boilerplate, and
  • deploy initial production, staging and development environments.

As such we have a "production" environment on day one and are strongly motivated to make sure that adding features allows progressive enhancement of the existing deployment. We are also strongly motivated to build in audience limiting features from the start if it is necessary to restrict access to the service as it is being developed.