Skip to content
All case studies

Platform & DevOps · Jul – Sep 2026

Untangling shared cloud projects under live customers

Two products shared Google Cloud projects whose boundaries no longer matched their environments. Separating them meant moving sign-in, mail sync and API credentials while customers kept working.

2
products moved
3
environments each
0
minutes of downtime
1
runbook, reused

Context

Both products lean on Google for sign-in, mailbox sync, maps and calendar. The cloud projects those credentials lived in had grown the way things grow when a team is busy shipping: one project quietly served several environments, names stopped describing what they held, and a change meant for one place could reach another.

The AWS side had already been tidied into one account per product with clean stages. I wanted Google Cloud to match, so that each environment owned its credentials outright and the next move would be a repeat of a known procedure rather than a fresh adventure.

Constraints

  • Real users on everything above dev, and no appetite for a downtime window.
  • Mailbox sync depends on push subscriptions that renew on their own schedule. Retire the old project too early and mail silently stops arriving, with no error anywhere.
  • OAuth consent screens cannot be copied between projects. Every client, redirect and scope had to be recreated and re-verified by hand.
  • Some services read the same credentials but deploy separately. Those are exactly the consumers an inventory built from one repository misses.
  • Credentials are read at deploy time. Writing a new value changes nothing until every consumer has been redeployed.

Approach

I started with an inventory, not a plan. Every consumer of every project was listed from the outside in: deployed configuration first, source code second. That is what surfaced a separately deployed service nobody had on the list, and it had to move in the same wave as everything else.

  • Stand up the new project and recreate its clients, redirects, scopes and API keys, this time restricted by referrer and IP, which the old projects never had.
  • Write the new credentials, then redeploy every consumer together, so the swap and the code that reads it land as one step.
  • Verify sign-in, mail sync and calendar on the new project before touching anything old.
  • Leave the old project running until every push subscription has rolled over and a full login cycle has been seen. Only then decommission.
  • Rehearse on dev, fix the runbook, then repeat on the next environment. The second product reused the same runbook with fewer moving parts.

Outcome

Each environment now runs on its own project, with names that mean something, restricted keys where there were none, and a written procedure a colleague can follow without me in the room.

Nobody outside the team noticed, which was the whole point.

What I'd do differently

  • Build the inventory from what is deployed before what is in source. Code tells you what could read a credential; the running estate tells you what does.
  • Treat 'new value written' as a no-op in the runbook. The redeploy is the change.
  • Put the subscription renewal window in the calendar on day one, so nobody tidies away a project that still has live listeners.