Backstage Integration: Software Catalog and ArgoCD Plugin
Backstage Integration: Software Catalog and ArgoCD Plugin
The Failure
The team had five services, each with its own dashboard, its own runbook location, its own deployment status page. A new developer needed to find the Grafana dashboard for the payments service. They asked three people before someone pointed them to a bookmark in a Slack channel. The team had tools but no index.
Backstage is the index. One portal where developers find every service, its documentation, its deployment status, its health, its dependencies, and its API.
The Mechanism
Backstage Components
| Component | Purpose |
|---|---|
| Software Catalog | Registry of all services, APIs, resources |
| Scaffolder | Create new services from templates |
| TechDocs | Documentation rendered from markdown in repos |
| Plugins | Extend with ArgoCD, Grafana, PagerDuty, GitHub |
Entity Relationships
System: ecommerce
└── Component: checkout-service
├── providesApi: checkout-api
├── consumesApi: inventory-api, payments-api
├── dependsOn: resource:postgres-checkout
└── ownedBy: group:checkout-team
The Implementation
Backstage app-config
# app-config.yaml
# HARDENED: Backstage configuration for e-commerce platform
app:
title: Acme Developer Portal
baseUrl: https://backstage.acme.com
organization:
name: Acme
catalog:
import:
entityFilename: catalog-info.yaml
rules:
- allow: [Component, System, API, Resource, Group, User]
locations:
# Discover all repos in the org
- type: github-discovery
target: https://github.com/acme/*/blob/main/catalog-info.yaml
# ArgoCD plugin
argocd:
appLocatorMethods:
- type: config
instances:
- name: production
url: https://argocd.acme.com
token: ${ARGOCD_AUTH_TOKEN}
# TechDocs
techdocs:
builder: "external"
generator:
runIn: "docker"
publisher:
type: "awsS3"
awsS3:
bucketName: acme-techdocs
region: us-east-1
System Entity
# ecommerce-infra/catalog-info.yaml
apiVersion: backstage.io/v1alpha1
kind: System
metadata:
name: ecommerce
description: Multi-service e-commerce platform
annotations:
backstage.io/techdocs-ref: dir:.
spec:
owner: platform-team
domain: commerce
Service Entity with ArgoCD
# checkout-service/catalog-info.yaml
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: checkout-service
description: Cart checkout and order creation
annotations:
github.com/project-slug: acme/checkout-service
backstage.io/techdocs-ref: dir:.
argocd/app-name: checkout-production
grafana/dashboard-selector: app=checkout-service
pagerduty.com/service-id: PXXXXXX
tags:
- go
- grpc
- critical
links:
- url: https://grafana.acme.com/d/checkout
title: Metrics Dashboard
icon: dashboard
- url: https://github.com/acme/checkout-service/actions
title: CI Pipeline
icon: github
spec:
type: service
lifecycle: production
owner: checkout-team
system: ecommerce
providesApis:
- checkout-api
consumesApis:
- inventory-api
- payments-api
dependsOn:
- component:inventory-service
- resource:postgres-checkout
---
apiVersion: backstage.io/v1alpha1
kind: API
metadata:
name: checkout-api
description: Checkout REST API
spec:
type: openapi
lifecycle: production
owner: checkout-team
system: ecommerce
definition:
$text: ./api/openapi.yaml
Resource Entity
# In ecommerce-infra/catalog-info.yaml
apiVersion: backstage.io/v1alpha1
kind: Resource
metadata:
name: postgres-checkout
description: PostgreSQL database for checkout service
spec:
type: database
owner: platform-team
system: ecommerce
dependencyOf:
- component:checkout-service
TechDocs in Service Repo
# checkout-service/mkdocs.yml
site_name: Checkout Service
nav:
- Home: index.md
- Architecture: architecture.md
- API: api.md
- Runbook: runbook.md
- ADRs:
- ADR-001 Go over Java: adrs/001-go-over-java.md
- ADR-002 gRPC for internal: adrs/002-grpc-internal.md
plugins:
- techdocs-core
Developer Workflow with Backstage
- Developer opens Backstage portal
- Clicks “Create” → selects “Go Microservice” template
- Fills in: name, team, description
- Backstage scaffolds the repo, creates infra entry, registers in catalog
- Developer clones the repo and starts coding
- The CI pipeline, security scans, deployment, and monitoring are already configured
- The service appears in the catalog with links to ArgoCD, Grafana, and PagerDuty
Time to first deploy: 10 minutes (from "Create" to running in staging)
The Gate
The software catalog is the visibility gate. Every service must have a catalog-info.yaml. Services without one are invisible to the organization. The platform team runs a weekly audit: any repo without a catalog entry gets an automated PR adding one.
The Recovery
Backstage is slow with many entities: Enable search indexing. Use the GitHub discovery provider’s schedule option to reduce API calls. Cache entity processing.
ArgoCD plugin shows stale data: The plugin polls ArgoCD’s API. If ArgoCD is behind a VPN and Backstage is not, the plugin cannot reach it. Use ArgoCD’s webhook notifications to push status to Backstage instead.
Developers do not use Backstage: Make it the default “how do I find X?” answer. Every time someone asks “where is the dashboard for Y?”, respond with the Backstage link. Adoption is a habit, not a mandate.