Skip to main content

DevEx & Backstage

The developer experience ecosystem provides self-service infrastructure provisioning, an internal developer portal, reusable templates, and documentation standards. It spans three primary repositories and integrates tightly with the Foundations platform layer.

Repositories

RepositoryPurposeLink
repo-devex-backstageBackstage internal developer portalbadal-io/repo-devex-backstage
backstage-templatesBackstage scaffolder templates for self-servicebadal-io/backstage-templates
badal-documentation-standardDocumentation standards and bootstrap scriptsbadal-io/badal-documentation-standard

Backstage Portal

Architecture

The Backstage portal is built on the Backstage open-source framework and deployed as a containerized application on GCP.

Infrastructure components:

ComponentTechnologyDetails
Application runtimeCloud RunHosts the Backstage frontend and backend
DatabaseCloud SQL PostgreSQL 15Stores catalog, scaffolder state, and plugin data
Secret managementHashiCorp VaultManages sensitive configuration and credentials
Container registryGoogle Artifact RegistryStores Backstage Docker images
NetworkingVPC + Cloud NATPrivate networking with outbound internet access

Authentication

Backstage uses a dual authentication pattern:

  • User authentication: OAuth via GitHub and Google identity providers. Users sign in through the Backstage UI and receive session-scoped tokens.
  • Backend service authentication: Vault JWT tokens and Application Default Credentials (ADC) for service-to-service communication between Backstage backend plugins and GCP/TFC APIs.

Custom Plugins

The portal includes 15 custom plugins:

PluginTypePurpose
homepage-linksFrontendCurated links and quick actions on the home page
claude-flowFrontend + BackendAI-assisted developer workflows using Claude
vault-secretsFrontend + BackendBrowse and manage HashiCorp Vault secrets
terraform-cloudFrontend + BackendView TFC workspace status, runs, and state
mockupFrontendUI mockup and prototyping tools
gemini-agentFrontend + BackendAI agent integration using Google Gemini

Each plugin with a backend component follows the Backstage plugin architecture with a frontend package (plugin-{name}) and a backend package (plugin-{name}-backend).

Backstage Templates

Available Templates

Five active templates are registered in the Backstage scaffolder:

TemplatePurposeTarget Repository
create-tenantCreate a new tenant within a business unitBU repo (PR to terraform/tenants/)
create-sandbox-projectCreate a standalone sandbox GCP projectSandbox workspace
create-business-unitCreate a new business unitgcp-foundations-projects
edit-tenant-moduleEdit an existing tenant's Terraform configurationBU repo (PR)
edit-business-unitEdit an existing business unit's configurationBU repo (PR)

Template Workflow

All templates follow a two-step wizard pattern:

  1. Basic configuration: User fills in name, description, environment selection, and other high-level parameters
  2. Terraform module editor: Interactive editor (via GithubTerraformModuleEditor custom field) that lets users configure the Terraform module variables with validation
  3. PR creation: The template creates a pull request to the target repository
  4. CI monitoring: The scaffolder monitors the PR's CI pipeline and reports status back

Custom UI Fields

The templates use three custom Backstage UI field extensions:

FieldPurposeUsage
GithubRepoPickerRepository selector with org-scoped searchSelect target repositories for PRs
GithubTeamPickerTeam selector with org-scoped searchAssign team permissions to new repos
GithubTerraformModuleEditorInteractive Terraform variable editorConfigure module variables with type validation, defaults, and descriptions

The GithubTerraformModuleEditor reads the Terraform module's variables.tf and renders a form with appropriate input controls for each variable type (string, number, bool, list, map, object).

Custom Scaffolder Actions

Templates use custom scaffolder actions to:

  • Create pull requests on existing repositories (rather than creating new repos)
  • Read backstage-manifest.json from BU repos to populate environment and configuration data
  • Validate Terraform variable configurations before PR creation
  • Monitor GitHub Actions CI runs on the created PRs

Backstage Catalog Integration

catalog-info.yaml

Every repository in the Foundations ecosystem includes a catalog-info.yaml file that registers the component in Backstage's software catalog:

apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: my-tenant
description: Description of the tenant
annotations:
github.com/project-slug: badal-io/my-repo
backstage.io/techdocs-ref: dir:.
tags:
- tenant
- gcp
spec:
type: service
lifecycle: production
owner: team-name

backstage-manifest.json

Business unit repositories contain a backstage-manifest.json file (generated by the BU module) that provides machine-readable metadata:

  • Repository and BU identity
  • WIF host project details
  • Environment folder IDs and org/billing configuration
  • TFC workspace and project references
  • GAR configuration
  • Service account and WIF provider URIs

This file is consumed by Backstage templates when creating or editing tenants, pre-populating environment configuration and folder references.

Documentation Standards

Repository: badal-documentation-standard

The badal-documentation-standard repository defines two documentation standards:

StandardToolUse Case
GenericMkDocs (Material theme)General-purpose repositories, services, applications
TerraformDocusaurusTerraform modules, infrastructure-as-code repositories

Generic Standard (MkDocs)

  • Uses MkDocs Material theme
  • Standard directory structure: docs/, mkdocs.yml
  • Includes search, navigation, and code highlighting
  • Supports diagrams via Mermaid

Terraform Standard (Docusaurus)

  • Uses Docusaurus with a Terraform-focused configuration
  • Auto-generates variable and output documentation from .tf files
  • Integrates with the TFC module registry

Bootstrap Process

Both standards include a bootstrap script that can be curl-piped to initialize documentation in any repository:

# Generic standard
curl -sSL https://raw.githubusercontent.com/badal-io/badal-documentation-standard/main/generic/bootstrap.sh | bash

# Terraform standard
curl -sSL https://raw.githubusercontent.com/badal-io/badal-documentation-standard/main/terraform/bootstrap.sh | bash

The bootstrap script:

  1. Auto-discovers the git context (repo name, org, remote URL)
  2. Creates the documentation directory structure
  3. Generates a catalog-info.yaml for Backstage registration
  4. Initializes configuration files (mkdocs.yml or docusaurus.config.js)
  5. Creates starter documentation pages

End-to-End Self-Service Flow

The typical self-service flow for creating a new tenant:

  1. Developer opens Backstage portal and selects "Create Tenant" template
  2. Fills in tenant name, selects business unit, chooses environments
  3. Uses the Terraform module editor to configure variables
  4. Template creates a PR to the BU repository's terraform/tenants/ directory
  5. CI runs terraform plan on the PR (with mock credentials)
  6. PR is reviewed and merged
  7. CI runs terraform apply, creating the tenant's GCP projects, repo, and workspaces
  8. The new tenant repository appears in Backstage's catalog via catalog-info.yaml
  9. The tenant team begins using their repository with the foundations-template scaffold