Platform Engineering 101: IDP with Backstage
Replace scattered DevOps toolchains with a paved road — a practical guide to building an Internal Developer Platform using Backstage.
Ask any engineer at a fast-growing startup what slows them down most and you will rarely hear "writing code." You will hear "waiting for environments," "figuring out how to deploy," and "no idea where the docs are." These are not engineering problems. They are toolchain and process problems. Platform Engineering exists to solve them.
An Internal Developer Platform (IDP) is the answer — a curated, self-service layer that sits between your engineers and your infrastructure, so developers can deploy, monitor, and operate services without becoming infrastructure experts.
The Core Architectural Challenge
Before the platform exists, a new engineer joining a team like Swiggy's backend goes through something like this: ask someone for access to the Kubernetes cluster, wait two days for the ticket, figure out which Helm chart to use, find the outdated README, ask on Slack, eventually get something running.
With a platform in place, they open a browser, fill a form, and a service is scaffolded, deployed to staging, wired to monitoring, and added to the service catalog — in twelve minutes.
That twelve-minute flow is the promise of platform engineering. Backstage is the most widely-adopted foundation for building it.
What Is Backstage and What Does It Give You Out of the Box?
Backstage is an open-source developer portal framework built by Spotify and donated to the CNCF. It is not a finished product — it is a plugin-based framework you assemble around your organization's specific tools and workflows.
Out of the box, Backstage gives you:
- A software catalog — a searchable registry of every service, API, library, and resource your organization runs
- Software templates — forms that scaffold new services with your standards baked in
- A plugin ecosystem — 200+ community plugins for Kubernetes, GitHub Actions, PagerDuty, Datadog, and more
The catalog and templates are where most teams start, and they deliver the most immediate value.
The Core Stack: What Goes Around Backstage
Backstage is the portal layer. The IDP underneath it is a stack of tools wired together:
Engineer | vBackstage (portal + catalog + templates) | +-- GitHub / GitLab (source of truth) | +-- Argo CD / Flux (GitOps delivery) | +-- Crossplane / Terraform (infra provisioning) | +-- Prometheus + Grafana (observability) | +-- Kubernetes (runtime)When an engineer clicks "Create New Service" in Backstage, a Software Template triggers a Cookiecutter or Nunjucks scaffold, opens a PR in GitHub, Argo CD detects the new manifests, and the service is deployed — all without the platform team being involved.
How Do You Set Up Your First Backstage Instance?
## Create Backstage appnpx @backstage/create-app@latest --skip-installcd my-backstage-appyarn install ## Start locally, opens at localhost:3000yarn devThe initial setup gets you the UI and catalog. The real work is connecting Backstage to your existing tools via the app-config.yaml:
integrations: github: - host: github.com token: ${GITHUB_TOKEN} catalog: locations: - type: url target: https://github.com/your-org/catalog/blob/main/all.yaml rules: - allow: [Component, API, System] kubernetes: serviceLocatorMethod: type: multiTenant clusterLocatorMethods: - type: config clusters: - url: https://k8s.internal.yourplatform.net name: production authProvider: serviceAccountThis wires Backstage to GitHub for catalog discovery and to your production Kubernetes cluster so engineers can see pod status, logs, and Argo CD sync state directly in the portal.
Building a Software Template
Software Templates are the most powerful Backstage feature. This is a minimal template that scaffolds a Node.js microservice:
apiVersion: scaffolder.backstage.io/v1beta3kind: Templatemetadata: name: nodejs-microservice title: Node.js Microservice description: Scaffold a production-ready Node.js servicespec: owner: platform-team type: service parameters: - title: Service Details properties: name: title: Service Name type: string owner: title: Owning Squad type: string steps: - id: fetch name: Fetch Template action: fetch:template input: url: ./skeleton values: name: ${{ parameters.name }} owner: ${{ parameters.owner }} - id: publish name: Create GitHub Repo action: publish:github input: repoUrl: github.com?owner=your-org&repo=${{ parameters.name }} - id: register name: Register in Catalog action: catalog:register input: repoContentsUrl: ${{ steps.publish.output.repoContentsUrl }} catalogInfoPath: /catalog-info.yamlWhen a developer fills this form, Backstage creates the repo, scaffolds the code from your skeleton, and registers the new service in the catalog — automatically.
The Service Catalog: Your Organization's Memory
The catalog is a YAML-driven registry. Each service has a catalog-info.yaml in its repo:
apiVersion: backstage.io/v1alpha1kind: Componentmetadata: name: order-service description: Handles order lifecycle for the platform annotations: github.com/project-slug: your-org/order-service backstage.io/kubernetes-id: order-service pagerduty.com/service-id: P12345spec: type: service lifecycle: production owner: order-squad dependsOn: - component:payment-service - component:inventory-serviceThe dependsOn field is what makes the catalog genuinely useful during incidents: you can click on order-service and immediately see which other services it depends on, who owns them, and whether they are healthy.
What to Expect in Year One
Most platform teams underestimate the cultural work. The technology is straightforward — getting 200 engineers to actually use the portal, keep their catalog-info.yaml updated, and stop deploying via direct kubectl apply is where the real effort goes.
Two things that work: mandate that new services must be created through the template (so adoption is automatic for new work), and make the catalog the canonical source for on-call routing and runbook links (so engineers have a reason to keep it updated).
Production Implementation Guidelines
Start with three things only: the catalog, one template, and the Kubernetes plugin. Don't try to integrate everything at once. A useful, partially-populated catalog is better than a perfect empty one.
Run Backstage on Kubernetes using the official Helm chart. Use a PostgreSQL database for the catalog backend — the default in-memory SQLite will lose your catalog every time the pod restarts.
helm repo add backstage https://backstage.github.io/charts## install with your customized values.yamlhelm install backstage backstage/backstage \ --values values.yamlUse Crossplane or Terraform Cloud alongside Backstage for infrastructure provisioning — Backstage is the interface, but it should not do the provisioning itself. Backstage triggers workflows; Crossplane or Terraform executes them.
Trade-offs and Alternatives
| Option | Best For | Limitation |
|---|---|---|
| Backstage | Large orgs, customization | High setup investment |
| Cortex | Catalog + scorecards | Less template flexibility |
| Port | Fast time-to-value | Vendor lock-in |
Backstage wins when you have a dedicated platform team (even one person) and more than 30-40 engineers. Below that, the setup cost outweighs the benefit — use a simpler catalog like Cortex or just a well-maintained Notion page.
NoteReferences and Further Reading
- Backstage Documentation - Official setup and plugin development guide
- CNCF Platforms White Paper - Platform engineering principles
- Backstage Plugin Marketplace - 200+ community plugins
- Crossplane Documentation - Infrastructure provisioning layer
Frequently Asked Questions
Does Backstage handle infrastructure provisioning itself?
No — Backstage is the interface layer that triggers workflows, but the actual provisioning should be handled by a separate tool like Crossplane or Terraform. Backstage shouldn't own the provisioning logic itself.
What database should a production Backstage instance use for the catalog?
PostgreSQL — the default in-memory SQLite backend loses the entire catalog every time the pod restarts, which makes it unsuitable for anything beyond local testing.
Is Backstage worth adopting for a small engineering team?
Usually not below roughly 30-40 engineers or without at least one dedicated platform engineer — the setup investment outweighs the benefit at smaller scale, where a simpler catalog tool like Cortex or even a well-maintained internal wiki page can cover the same need.
What's the biggest challenge in getting Backstage adoption right, technology aside?
The cultural work — getting engineers to actually use the portal, keep their catalog-info.yaml updated, and stop deploying via direct kubectl apply is consistently harder than the technical setup itself.
What should a team integrate first when starting with Backstage?
Just three things — the software catalog, one Software Template, and the Kubernetes plugin. Trying to integrate everything at once slows initial adoption; a useful, partially-populated catalog delivers more value early than a perfect but empty one.
Discussion0