npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@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.

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-gcp

Dependencies

  • googleapis — Google APIs Node.js client
  • google-auth-library — Authentication via Application Default Credentials
  • @backstage/catalog-model — Backstage entity types
  • @backstage/plugin-catalog-nodeEntityProvider interface
  • @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-only

In a local environment, authenticate with:

gcloud auth application-default login

In 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, and lifecycleLabel in app-config.yaml. The default for lifecycleLabel is "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-api

Building

npm run build    # Compiles TypeScript to dist/
npm run clean    # Removes dist/

License

MIT