Skip to main content
ship it and sleep

Backstage Integration: Software Catalog and ArgoCD Plugin

4 min read Chapter 66 of 66

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

ComponentPurpose
Software CatalogRegistry of all services, APIs, resources
ScaffolderCreate new services from templates
TechDocsDocumentation rendered from markdown in repos
PluginsExtend 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

  1. Developer opens Backstage portal
  2. Clicks “Create” → selects “Go Microservice” template
  3. Fills in: name, team, description
  4. Backstage scaffolds the repo, creates infra entry, registers in catalog
  5. Developer clones the repo and starts coding
  6. The CI pipeline, security scans, deployment, and monitoring are already configured
  7. 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.