The ticket queue is the symptom, not the disease
Every platform team ends up as a ticket queue. Someone needs a bucket, a service account, a Cloud SQL instance; they file a request; an engineer picks it up, runs some Terraform, and closes it. The work is trivial and the wait is days. What makes it worse is that the queue hides the real problem — nobody knows what good looks like, so every request is bespoke, and the platform team becomes the only place that knowledge lives.
Golden paths before portals
A self-service portal in front of an inconsistent platform just automates the inconsistency. The first work is deciding what a 'standard service' actually is — which region, which labels, which IAM shape, which budget alert, what gets backed up. Once that exists as a template, the portal is a thin front end over it. Skip this step and you build a UI for filing the same bespoke requests faster.
Config Connector: cloud resources as Kubernetes objects
Rather than a separate Terraform run per request, GCP resources are declared as Kubernetes custom resources and reconciled by a controller in-cluster. A Cloud SQL instance becomes a manifest that lives beside the workload that uses it, with the same RBAC, the same GitOps flow and the same drift correction. The mental model collapses from two systems to one.
kubectl get gcpsqlinstance,gcpstoragebucket,iamserviceaccount -A \
-o custom-columns=KIND:.kind,NS:.metadata.namespace,NAME:.metadata.name,READY:.status.conditions[0].statusEverything the platform manages, in one query. This view is what the ticket queue was hiding — you cannot audit what only exists in closed tickets.
Atlantis: the plan goes in the pull request
Terraform applied from a laptop is unreviewable and unrepeatable. Atlantis runs plan on the PR and posts the output as a comment, so the reviewer sees exactly what will change before approving, and apply happens from CI with a locked state file. The audit trail is the PR — who asked, who approved, what changed, when.
# in the PR, as comments:
atlantis plan -d envs/prod
atlantis apply -d envs/prod # only after approvalApply is gated on PR approval, so the review is on the plan output rather than on the diff of the HCL — which is what actually matters.
What goes wrong
Three failures are near-universal. State locking: two applies racing leaves a lock behind and every later run blocks — you need a documented force-unlock path or the platform team becomes the ticket queue again. Drift: someone fixes something in the console at 2am and the next apply reverts it, so drift detection has to run continuously rather than at apply time. And permission sprawl: the portal's service account accumulates roles until it can do anything, which quietly makes it the most dangerous identity in the org.
terraform force-unlock <LOCK_ID> # only after confirming no apply is running
terraform plan -detailed-exitcode # exit 2 = drift; run it on a scheduleThe -detailed-exitcode flag is the one people miss: exit 0 no changes, 1 error, 2 drift. That makes drift a CI signal rather than a discovery.