Quick Reference
Naming Cheat Sheet
payments - prod - api
│ │ └── service → Backstage Component (base) → gateway-api
│ └────────── env → ArgoCD Application suffix → gateway-api-prod
└──────────────────── project → Backstage Domain → payments
→ ArgoCD AppProject
gcp - payments - prod - cloudsql - main
│ │ │ │ └── name
│ │ │ └──────────── resource type → spec.type: database
│ │ └───────────────────── env → infra ns: payments-prod-infra
│ └──────────────────────────────── project → Backstage Domain
└────────────────────────────────────── provider → compositionSelector.provider
System Correspondence
payments → AppProject: payments → Domain: payments
gateway → ApplicationSet: gateway → System: gateway
gateway-api → Application base → Component: gateway-api
gateway-api-prod → Application instance → observed via ArgoCD plugin
payments-prod-api → Application destination ns → observed via k8s plugin
gcp-payments-prod-cloudsql-main → Crossplane Claim → Resource entity
Required Labels on Every Namespace (9 Total)
| Label | Example | Purpose |
|---|---|---|
project | payments | Group namespaces by domain |
env | prod | Target policies, quotas, RBAC by env |
service | api | Identify the workload |
team | team-payments | Ownership for alerts |
backstage.io/domain | payments | Traceability → Backstage Domain |
backstage.io/system | gateway | Traceability → Backstage System |
backstage.io/component | gateway-api | Backstage k8s plugin label selector |
argocd/app | gateway-api-prod | Traceability → ArgoCD Application |
argocd/app-set | gateway | Traceability → ApplicationSet |
Cross-System Navigation
# Namespace → ArgoCD Application
kubectl get ns payments-prod-api -o jsonpath='{.metadata.labels.argocd/app}'
# → gateway-api-prod
# Namespace → Backstage Component
kubectl get ns payments-prod-api -o jsonpath='{.metadata.labels.backstage\.io/component}'
# → gateway-api
# ArgoCD Application → namespace
argocd app get gateway-api-prod -o json | jq '.spec.destination.namespace'
# → payments-prod-api
# All namespaces for a component (all envs, all clusters)
kubectl get ns -l backstage.io/component=gateway-api
# All ArgoCD Applications for a system
argocd app list -l argocd/app-set=gateway
# All prod namespaces
kubectl get ns -l env=prod
# Crossplane Claim status
kubectl get cloudsqlinstance cloudsql-main -n payments-prod-infra
# NAME READY SYNCED EXTERNAL-NAME AGE
# cloudsql-main True True payments-prod-cloudsql-main 5m
Production Safeguards
| Safeguard | How it is enforced |
|---|---|
| No auto-deploy to prod | ArgoCD syncWindows: deny + templatePatch removes automated block |
| No accidental DB deletion | Crossplane deletionPolicy: Orphan on all prod Claims |
| No convention bypass | GitHub Actions (validate-conventions.yaml) automatically runs validate-namespaces.sh to block PR merges |
| Developer prod block | Prod RoleBinding not created for developer role |
| No plain-text secrets | Sealed Secrets via create-secret Backstage template |
Responsibility Matrix
| Concern | Owner | Mechanism |
|---|---|---|
| What a component is | Backstage | Domain / System / Component entities |
| Who owns it | Backstage | spec.owner |
| Where it runs | Kubernetes | env label + namespace name |
| How it is deployed | ArgoCD | ApplicationSet → Application |
| What infrastructure it needs | Crossplane | Claim → Composite → Cloud resource |
| Runtime health per env | Backstage k8s plugin | label selector across all clusters |
| Sync status per env | Backstage ArgoCD plugin | app selector |
| Infrastructure READY/SYNCED | Backstage k8s plugin | Claim CRD label selector |
| Access control | Kubernetes RBAC | RoleBinding (Group subject) per namespace |
| Traffic isolation | Kubernetes | NetworkPolicy by project label |
| Resource limits | Kubernetes | ResourceQuota per namespace |
| Convention enforcement | Templates + CI | Scaffolder + GitHub Actions validate |
Full Architecture Diagram
┌─────────────────────────────────────────────────────────────────────────┐
│ Backstage Catalog │
│ Domain System Component Resource │
│ payments gateway gateway-api gcp-payments-prod-cloudsql │
│ ├── k8s tab → health per env per cluster │
│ ├── argo tab → sync status per env │
│ └── deps → cloudsql ← READY/SYNCED via k8s │
└──────────┬──────────────────────────────────┬───────────────────────────┘
│ k8s + argocd plugins │ k8s plugin (Claim CRD)
┌──────────▼──────────────┐ ┌────────────▼─────────────────────────┐
│ ArgoCD │ │ Kubernetes clusters │
│ cluster-mgmt/argocd │ │ │
│ │ │ cluster-dev payments-dev-api │
│ AppProject: payments │ │ cluster-stg payments-staging-api │
│ AppProject: platform │ │ cluster-prod payments-prod-api │
│ │ │ │
│ AppSet: gateway ───┼───────┼►payments-<env>-api (per cluster) │
│ │ │ │
│ AppSet: crossplane ───┼───────┼►cluster-mgmt │
│ -claims │ │ payments-prod-infra/cloudsql-main │
│ │ │ READY: True SYNCED: True │
│ AppSet: platform ───┼───────┼►platform-<env>-monitoring │
└──────────┬───────────────┘ └──────────────┬────────────────────────┘
│ syncs │ Crossplane reconciles
┌──────────▼───────────────────────────────────────▼───────────────────────┐
│ Git Repositories │
│ platform-gitops/ <domain>-gitops/ │
│ ├── argocd/projects/ ├── k8s/<env>/<service>/ │
│ ├── argocd/applicationsets/ ├── crossplane/claims/<env>/<type>/ │
│ ├── crossplane/providers/ └── catalog/ │
│ ├── crossplane/xrds/ │
│ ├── crossplane/compositions/ Cloud Providers │
│ ├── k8s/platform/ ────► GCP / AWS / Azure / IBM │
│ ├── k8s/rbac/ │
│ └── backstage-templates/ │
└──────────────────────────────────────────────────────────────────────────┘