The Internal Developer Platform as a Product
Stop asking every team to reinvent CI, infra and observability. Pave a golden path, ship it as a product, and let developers go from idea to running service before lunch.
For a decade the answer to "who runs this service?" was "the team that wrote it, end to end." That was the promise of you-build-it-you-run-it. The reality, at scale, is forty teams each hand-rolling their own Terraform, their own pipeline, their own alerting, and quietly drifting apart. Platform engineering is the correction: take the undifferentiated heavy lifting, turn it into a paved road, and ship that road as an internal product.
The shift is not about taking ownership away from product teams. It is about lowering the cognitive load required to ship safely, so that the autonomy you gave them is actually usable. A team that has to understand IAM trust policies, VPC peering and Prometheus relabelling before it can deploy a CRUD service does not feel empowered. It feels stuck.
Why "everyone does their own DevOps" stopped scaling
The original DevOps movement tore down the wall between dev and ops by asking developers to operate what they build. It worked, and then it overshot. Every stream-aligned team became a part-time platform team, and the cost showed up everywhere at once.
- Cognitive load. The list of things a feature engineer is expected to know, Kubernetes, Terraform, secrets, SLOs, supply-chain security, grew faster than anyone could learn it. Extraneous load crowded out the actual product work.
- Divergence. Forty bespoke pipelines means forty different ways to roll back, forty places a CVE can hide, and no single lever to pull when something org-wide needs to change.
- Onboarding tax. A new hire on team A learns nothing transferable to team B. Tribal knowledge replaces a shared mental model.
- No leverage. When security mandates SBOMs or signed images, you are now filing forty tickets and chasing forty backlogs instead of upgrading one template.
Platform engineering answers this with self-service and golden paths: an opinionated, supported, well-lit route through the common case, so the common case takes minutes and the unusual case is still possible.
The IDP is a product with a paved road
An Internal Developer Platform is not a wiki of runbooks. It is a product, with users (your developers), a backlog, and a definition of success. Treat it like one and the paved road assembles from a few concrete capabilities working together.
- A portal. Backstage or an equivalent gives a software catalog, ownership metadata, and a place where scaffolding templates live next to the docs and the dashboards.
- Scaffolding. "Create a new service" generates a repo from a golden template, pre-wired with the language toolchain, a Dockerfile, health checks and a sane project layout.
- CI/CD templates. Reusable pipeline definitions, build, test, scan, sign, deploy, that a service inherits rather than copies. Fix the template, fix every consumer.
- IaC modules. Versioned Terraform or Crossplane modules for a namespace, a database, a queue, exposed as parameters, not as a 300-line file to fork.
- Policy guardrails. OPA/Kyverno and CI checks that make the safe thing the default and the unsafe thing loud, not forbidden by a human gate.
Press Spin up a new service below and watch the golden path run end to end. Then flip Paved road off to see the same outcome the old way, gated on ops tickets, and compare what it costs.
A paved road, not a locked cage
The failure mode of an internal platform is not that it is too weak. It is that it becomes a cage. A platform team, burned once by a team that did something clever and broke production, starts removing options until the only way to ship is the way they personally approve. That is just centralized ops with a portal bolted on, and developers route around it.
The discipline is opinionated defaults with escape hatches. The golden path should cover the 80% case so completely that nobody wants to leave it. For the other 20%, leaving must be possible, documented, and not career-ending.
- Defaults, not mandates. A service gets a sensible namespace, network policy and dashboards out of the box, but a team can override the resource requests when their workload genuinely needs it.
- Eject without abandoning support. A team that needs a database flavour the module does not offer can drop to raw IaC for that one resource and keep the rest of the paved road.
- Guardrails express intent, not paranoia. Block public S3 buckets by policy; do not block every new IAM role behind a human approval. One is a guardrail, the other is a traffic jam.
- Pave the desire path. When you see teams repeatedly leaving the road at the same point, that is a feature request, not a violation. Pave where they actually walk.
If the escape hatch is scarier than the workaround, you built a cage. Developers will always find a way to ship. The only question is whether that way runs through your platform, where you have visibility and guardrails, or around it, where you have neither.
Concretely, a golden-path service template makes the opinionated choice the easy one while leaving the parameters open:
# platform/templates/service/golden-path.yaml
apiVersion: backstage.io/v1beta3
kind: Template
metadata:
name: rust-grpc-service
title: gRPC service (golden path)
spec:
parameters:
- title: Service
properties:
name: { type: string }
team: { type: string, ui:field: OwnerPicker }
tier: { type: string, enum: [bronze, silver, gold] } # SLO + alerting preset
steps:
- id: scaffold # repo from template: Dockerfile, CI, health checks
- id: pipeline # inherits reusable CI/CD workflow, not a fork
- id: infra # namespace + Postgres via versioned IaC module
- id: observe # dashboards, SLOs and secrets wired automatically
# escape hatch: override any default in infra/overrides.tf and keep the rest
Measuring the platform like the product it is
A platform you cannot measure is a faith-based investment, and finance will eventually ask for evidence. The good news is the metrics already exist; you just have to claim them. Lead with outcomes developers feel, then back them with delivery data.
- DORA. Deployment frequency, lead time for changes, change-failure rate and mean time to restore. A working platform moves all four in the right direction because it standardizes the path they all flow through.
- Time to first deploy. How long from "new repo" to "running in staging with a URL"? On a paved road this is minutes. The widget above is not hypothetical, it is the number to chase.
- Developer experience. Survey friction directly, SPACE or DevEx framing, and watch adoption: a good platform is pulled in, not pushed. If teams opt in without a mandate, the road is paved well.
- Cognitive load offloaded. Count the decisions a team no longer has to make. Every default the platform owns is one less thing in a feature engineer's head.
This is where Team Topologies gives the org chart a shape. The platform team is an enabling team, not a gatekeeper and not a shared-services ticket desk. It reduces the cognitive load of stream-aligned teams by providing a self-service platform, then gets out of the way. Success looks like teams needing the platform team less over time, not filing more tickets.
Takeaways
- Platform engineering exists to lower cognitive load, not to take ownership back from product teams.
- Ship the IDP as a product: portal, scaffolding, CI/CD templates, IaC modules and policy guardrails on one paved road.
- Opinionated defaults with documented escape hatches make a road; remove the hatches and you built a cage.
- Prove value with DORA, time-to-first-deploy and DevEx, and run the platform team as an enabling team that earns its way out of the loop.
Pave a golden path your developers actually want?
We stand up Backstage, golden-path templates, versioned IaC modules and policy guardrails so a new service goes from repo to staging in minutes, with guardrails, not gates.
Build your platform