Backstage
Cluster Registration
# app-config.yaml
kubernetes:
serviceLocatorMethod:
type: multiTenant
clusterLocatorMethods:
- type: config
clusters:
- {name: mgmt, url: https://kubernetes.default.svc, authProvider: serviceAccount, serviceAccountToken: ${K8S_MGMT_TOKEN}, caData: ${K8S_MGMT_CA}}
- {name: dev, url: https://k8s-dev.internal, authProvider: serviceAccount, serviceAccountToken: ${K8S_DEV_TOKEN}, caData: ${K8S_DEV_CA}}
- {name: staging, url: https://k8s-staging.internal, authProvider: serviceAccount, serviceAccountToken: ${K8S_STAGING_TOKEN}, caData: ${K8S_STAGING_CA}}
- {name: prod, url: https://k8s-prod.internal, authProvider: serviceAccount, serviceAccountToken: ${K8S_PROD_TOKEN}, caData: ${K8S_PROD_CA}}
# Enable Crossplane Claim CRDs in the k8s plugin
customResources:
- {group: platform.myorg.io, apiVersion: v1alpha1, plural: gkeclusters}
- {group: platform.myorg.io, apiVersion: v1alpha1, plural: cloudsqlinstances}
Domain
apiVersion: backstage.io/v1alpha1
kind: Domain
metadata:
name: payments
annotations:
backstage.io/source-location: url:https://github.com/myorg/payments-gitops
platform.myorg/slack-channel: "#team-payments"
scaffolder.backstage.io/template: create-domain
spec:
owner: team-payments
System
apiVersion: backstage.io/v1alpha1
kind: System
metadata:
name: gateway
annotations:
argocd/app-selector: project=payments,system=gateway
platform.myorg/environments: "dev,staging,prod"
platform.myorg/sync-policy: automated-prod-manual
platform.myorg/deployment-strategy: rolling
scaffolder.backstage.io/template: create-system
spec:
domain: payments
owner: team-payments
Component
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: gateway-api
annotations:
# One selector finds payments-dev-api, payments-staging-api, payments-prod-api
# across ALL registered clusters automatically
backstage.io/kubernetes-label-selector: >
project=payments,service=api
# Surfaces sync status and revision per env
argocd/app-selector: >
project=payments,service=api
backstage.io/source-location: url:https://github.com/myorg/payments-gitops
backstage.io/techdocs-ref: dir:.
platform.myorg/service-type: api
platform.myorg/image: ghcr.io/myorg/gateway-api
scaffolder.backstage.io/template: create-service
spec:
type: api
lifecycle: production
system: gateway
owner: team-payments
dependsOn:
- resource:gcp-payments-prod-gke-main
- resource:gcp-payments-prod-cloudsql-main
providesApis: [gateway-api-v1]
Resource
apiVersion: backstage.io/v1alpha1
kind: Resource
metadata:
name: gcp-payments-prod-cloudsql-main
annotations:
platform.myorg/iac-tool: crossplane
platform.myorg/iac-repo: myorg/payments-gitops
platform.myorg/iac-path: crossplane/claims/prod/cloudsql-main.yaml
platform.myorg/crossplane-claim-kind: CloudSQLInstance
platform.myorg/crossplane-claim-namespace: payments-prod-infra
argocd/app: crossplane-payments-prod-cloudsql-main
# Shows Claim READY/SYNCED conditions on the Resource page
backstage.io/kubernetes-label-selector: >
backstage.io/resource=gcp-payments-prod-cloudsql-main
platform.myorg/provider: gcp
platform.myorg/resource-type: cloudsql
platform.myorg/env: prod
scaffolder.backstage.io/template: create-resource
spec:
type: database
owner: team-payments
system: gateway # system-owned — shared by multiple gateway services
What the Component Page Shows
Component: gateway-api
│
├── Kubernetes tab (label selector: project=payments,service=api — all clusters)
│ ├── dev → payments-dev-api pods 1/1 ✅
│ ├── staging → payments-staging-api pods 2/2 ✅
│ └── prod → payments-prod-api pods 3/3 ⚠️ 1 restart
│
├── ArgoCD tab (app selector: project=payments,service=api)
│ ├── gateway-api-dev Synced ✅ v1.4.2
│ ├── gateway-api-staging Synced ✅ v1.4.1
│ └── gateway-api-prod OutOfSync ⚠️ v1.3.9
│
└── Relations tab
├── dependsOn: gcp-payments-prod-gke-main ← cluster it runs on
└── dependsOn: gcp-payments-prod-cloudsql-main ← database it uses
Catalog Registration
Each domain repo registers its own entities:
# payments-gitops/catalog-info.yaml
apiVersion: backstage.io/v1alpha1
kind: Location
metadata:
name: payments-catalog
spec:
targets:
- ./catalog/domain.yaml
- ./catalog/systems/gateway.yaml
- ./catalog/components/gateway-api.yaml
- ./catalog/components/gateway-worker.yaml
- ./catalog/resources/gcp-payments-prod-gke-main.yaml
- ./catalog/resources/gcp-payments-prod-cloudsql-main.yaml
# app-config.yaml
catalog:
locations:
- type: url
target: https://github.com/myorg/platform-gitops/blob/main/catalog-info.yaml
- type: url
target: https://github.com/myorg/payments-gitops/blob/main/catalog-info.yaml
- type: url
target: https://github.com/myorg/orders-gitops/blob/main/catalog-info.yaml