@nospt/backstage-plugin-catalog-gcp
v0.8.0
Published
A [Backstage](https://backstage.io) backend plugin that automatically discovers GCP resources and ingests them into the Backstage Software Catalog as **Resource** entities.
Keywords
Readme
backstage-plugin-catalog-gcp
A Backstage backend plugin that automatically discovers GCP resources and ingests them into the Backstage Software Catalog as Resource entities.
Supported Resource Types
| GCP Service | Config Key | Default spec.type | GCP API |
| ----------------------- | ------------------ | ---------------------- | -------------------------------------------- |
| Cloud Run Services | cloudRun | serverless | Cloud Run Admin API v2 |
| Cloud Storage Buckets | cloudStorage | storage | Cloud Storage JSON API v1 |
| Artifact Registry | artifactRegistry | artifact-registry | Artifact Registry API v1 |
| Cloud SQL (PostgreSQL) | cloudSQL | database | Cloud SQL Admin API v1beta4 |
| Memorystore Redis | memorystore | cache | Memorystore Redis API v1 |
| GKE Clusters | gke | container-cluster | Kubernetes Engine API v1 |
Each GCP project is also ingested as a Backstage System entity by GoogleCloudProjectEntityProvider (config key projects). All resource providers automatically set spec.system to the GCP project ID when no system label is found on the resource, so project-level relationships are established without any manual labelling.
Installation
npm install backstage-plugin-catalog-gcp
# or
yarn add backstage-plugin-catalog-gcpDependencies
googleapis— Google APIs Node.js clientgoogle-auth-library— Authentication via Application Default Credentials@backstage/catalog-model— Backstage entity types@backstage/plugin-catalog-node—EntityProviderinterface@backstage/backend-plugin-api— New Backend System services (LoggerService,SchedulerService)
Authentication
The plugin uses Application Default Credentials (ADC) with the read-only scope:
https://www.googleapis.com/auth/cloud-platform.read-onlyIn a local environment, authenticate with:
gcloud auth application-default loginIn production (GKE, Cloud Run, etc.), use Workload Identity or a service account key.
Required IAM roles on each target project:
| Resource Type | Required IAM Role |
| ------------------ | ------------------------------------------------------------------------- |
| Cloud Run | roles/run.viewer |
| Cloud Storage | roles/storage.objectViewer (bucket list requires project-level binding) |
| Artifact Registry | roles/artifactregistry.reader |
| Cloud SQL | roles/cloudsql.viewer |
| Memorystore Redis | roles/redis.viewer |
| GKE | roles/container.clusterViewer |
| Projects (System) | roles/resourcemanager.projectViewer |
Usage
This plugin ships as a New Backend System module. Add it to your backend in packages/backend/src/index.ts:
import { createBackend } from '@backstage/backend-defaults';
const backend = createBackend();
// ... other plugins
backend.add(import('backstage-plugin-catalog-gcp-backend'));
backend.start();The module (catalogModuleGcpEntityProviders) automatically reads configuration from app-config.yaml, creates all enabled providers, and registers them with the catalog using SchedulerService for lifecycle management.
Advanced: manual wiring
If you need to use the providers directly (e.g. in a custom module or test), import the provider classes and pass logger and scheduler from @backstage/backend-plugin-api:
import {
GoogleCloudRunEntityProvider,
GoogleCloudProjectEntityProvider,
} from 'backstage-plugin-catalog-gcp-backend';
// deps: { client: GcpClient, logger: LoggerService, scheduler: SchedulerService }
const providers = GoogleCloudRunEntityProvider.fromConfig(config, deps);Configuration
Add provider configuration under catalog.providers.gcp in your app-config.yaml:
catalog:
providers:
gcp:
# Ingest GCP projects as System entities
projects:
- ownerLabel: owner
schedule:
frequency: { hours: 6 }
timeout: { minutes: 5 }
initialDelay: { seconds: 10 }
cloudRun:
- projectIds:
- my-gcp-project
ownerLabel: owner
componentLabel: component
systemLabel: system # Falls back to GCP project ID when absent
lifecycleLabel: environment # GCP label key → spec.lifecycle
resourceType: serverless
disabled: false
schedule:
frequency: { hours: 1 }
timeout: { minutes: 5 }
initialDelay: { seconds: 15 }
cloudStorage:
- projectIds:
- my-gcp-project
ownerLabel: owner
componentLabel: component
systemLabel: system
lifecycleLabel: environment
resourceType: storage
disabled: false
schedule:
frequency: { hours: 1 }
timeout: { minutes: 5 }
initialDelay: { seconds: 15 }
artifactRegistry:
- projectIds:
- my-gcp-project
ownerLabel: owner
componentLabel: component
systemLabel: system
lifecycleLabel: environment
resourceType: artifact-registry
disabled: false
schedule:
frequency: { hours: 1 }
timeout: { minutes: 5 }
initialDelay: { seconds: 15 }
cloudSQL:
- projectIds:
- my-gcp-project
ownerLabel: owner
componentLabel: component
systemLabel: system
lifecycleLabel: environment
resourceType: database
disabled: false
schedule:
frequency: { hours: 1 }
timeout: { minutes: 5 }
initialDelay: { seconds: 15 }
memorystore:
- projectIds:
- my-gcp-project
ownerLabel: owner
componentLabel: component
systemLabel: system
lifecycleLabel: environment
resourceType: cache
disabled: false
schedule:
frequency: { hours: 1 }
timeout: { minutes: 5 }
initialDelay: { seconds: 15 }
gke:
- projectIds:
- my-gcp-project
ownerLabel: owner
componentLabel: component
systemLabel: system
lifecycleLabel: environment
resourceType: container-cluster
disabled: false
schedule:
frequency: { hours: 1 }
timeout: { minutes: 5 }
initialDelay: { seconds: 15 }See docs/configuration.md for a full annotated reference.
Label Conventions
Entity metadata is extracted from GCP resource labels. Apply these labels to your GCP resources to control ownership, system grouping, and component relations in Backstage:
| GCP Label Key | Applied to | Backstage Field | Example Value | Effect |
| --------------- | --------------- | ------------------------ | -------------------- | ----------------------------------------------------------------------------------------- |
| owner | resource | spec.owner | team-platform | Sets the owning team/user. Defaults to unknown if missing |
| system | resource | spec.system | payments | Groups the resource under a Backstage System. Falls back to the GCP project ID when not set |
| environment | project | spec.lifecycle | production | Set on the GCP project. The System entity reads it directly; all resources in the project inherit it |
| component | resource | spec.dependsOn | checkout-api | Creates a dependsOn relation to a Component |
Tip: All label key names are configurable via
ownerLabel,componentLabel,systemLabel, andlifecycleLabelinapp-config.yaml. The default forlifecycleLabelis"environment".
The system fallback to the GCP project ID means every resource is automatically linked to the System entity created by GoogleCloudProjectEntityProvider, even without any labels.
Entity Structure
Each ingested GCP resource becomes a Backstage Resource entity. GCP projects become System entities:
# GCP Project → System entity
# The 'environment' label on the PROJECT drives spec.lifecycle for the System
# and is inherited by every resource within the project.
apiVersion: backstage.io/v1alpha1
kind: System
metadata:
name: my-gcp-project
namespace: default
title: My GCP Project
annotations:
google.com/project-id: my-gcp-project
labels:
environment: production # ← set this label on the GCP project itself
spec:
owner: team-platform
lifecycle: production # ← read from the project's 'environment' label
---
# GCP Resource (Cloud Run / Cloud SQL / GKE / etc.) → Resource entity
# lifecycle is inherited from the project — no need to set it on the resource
apiVersion: backstage.io/v1alpha1
kind: Resource
metadata:
name: my-cloud-run-service # sanitized from GCP resource name
namespace: default
annotations:
google.com/project-id: my-gcp-project
google.com/cloud-run-service-url: https://my-svc-abc123.run.app
labels:
owner: team-platform
system: payments
spec:
type: serverless
owner: team-platform
system: payments # falls back to "my-gcp-project" when label is absent
lifecycle: production # inherited from the project's 'environment' label
dependsOn:
- component:default/checkout-apiBuilding
npm run build # Compiles TypeScript to dist/
npm run clean # Removes dist/License
MIT
