Skip to content

Backstage Service Catalog

Backstage is our service catalog. It gives one place to answer the questions that otherwise mean digging through repositories, Slack threads and the memory of whoever built the project:

  • What systems do we have, and who owns them?
  • Where is each one deployed (Vercel, Cloudflare, etc.), and what is the production URL?
  • What stack does it run on: framework, CMS, commerce platform, third-party APIs?
  • Where do the logs go, which SLA tier applies, and which Busy/Jira project does it belong to?

Customer Support is the main audience. When a client gets in touch, CS needs to quickly find what the system is, where it runs, who to talk to and what agreement covers it, without having to ask a developer. A good catalog entry makes that possible. Developers benefit too: it is the quickest way to get oriented in a project you haven’t worked on before, or one you haven’t touched in a year.

The catalog is only useful if it is complete and correct. A product missing from Backstage, or one with outdated information, is a product CS can’t help with.

  • Every product we build and run has a backstage.yaml in the root of its repository.
  • The entry is written for someone who has never opened the codebase. Write descriptions as plain-language explanations, not boilerplate.
  • Everything in the file must be true for this repository. Products often share a stack, but they don’t share env var names, account IDs, space IDs or admin paths. Never copy these from a sibling project.
  • Keep the file up to date. When you add a component, change hosting, or start using a new third-party API, update backstage.yaml in the same PR.

The file is multi-document YAML, with entities in this order:

  1. System: the product as a whole (exactly one per file).
  2. API: HTTP surfaces we expose that another component calls (e.g. an internal /api/revalidate endpoint).
  3. Component: what we build and deploy, such as a web app, worker, mobile app or studio.
  4. Resource: infrastructure we provision, such as queues, durable objects and KV namespaces.

Shared services like Vercel, Cloudflare, Storyblok, Centra and HyperDX live in the central try-backstage-catalog. Reference them by name (resource:tryhuset/vercel, tryhuset/storyblok-api). Don’t redefine them in your product file.

Set these on the System so they show up on the Project card for every component:

Field What it tells CS
spec.owner (group:default/<gh-team-slug>) Which team owns the product
Production link The live site
Hosting link (Vercel / Cloudflare dashboard) Where it is deployed
CMS / commerce admin links Where the client manages content and products
try.no/sla-tier, try.no/sla-agreement Which SLA applies. CS is the source of truth
try.no/sla-client-domain The client’s production domain
try.no/project-owner The PM / project owner
busy.no/project-id, jira.com/project-key Where time is logged and issues are tracked
try.no/log-drain Where to look for logs (e.g. HyperDX, Vercel)
try.no/documentation External docs (Notion, Confluence, Storybook…)

Default try.no/sla-tier to standard. Check with CS before setting anything else.

The relations between entities are what make the catalog show how a system actually fits together:

  • consumesApis: who calls an API over HTTP. Use it for third-party APIs and for calls between our own components.
  • providesApis: who exposes an API. Needs a matching API entity.
  • dependsOn: platforms we run on and runtime bindings (hosting, queues, log drains). Not for HTTP.

Use one edge per relationship. If a component calls Storyblok over HTTP, that’s consumesApis: tryhuset/storyblok-api only. Don’t also add a dependsOn for it.

  • Use the Backstage agent skill to generate or update backstage.yaml. It inspects the repository, follows the conventions above and asks for the values it can’t verify, such as the GitHub team, production URL and Centra admin path.
  • Review the generated file before merging. Pay particular attention to URLs, IDs and env var names, since mistakes there tend to get through review.
  • Once merged, the product shows up in Backstage.
  • See try-backstage-catalog for shared entities and examples.