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
| Repository | Purpose | Link |
|---|---|---|
| repo-devex-backstage | Backstage internal developer portal | badal-io/repo-devex-backstage |
| backstage-templates | Backstage scaffolder templates for self-service | badal-io/backstage-templates |
| badal-documentation-standard | Documentation standards and bootstrap scripts | badal-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:
| Component | Technology | Details |
|---|---|---|
| Application runtime | Cloud Run | Hosts the Backstage frontend and backend |
| Database | Cloud SQL PostgreSQL 15 | Stores catalog, scaffolder state, and plugin data |
| Secret management | HashiCorp Vault | Manages sensitive configuration and credentials |
| Container registry | Google Artifact Registry | Stores Backstage Docker images |
| Networking | VPC + Cloud NAT | Private 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:
| Plugin | Type | Purpose |
|---|---|---|
| homepage-links | Frontend | Curated links and quick actions on the home page |
| claude-flow | Frontend + Backend | AI-assisted developer workflows using Claude |
| vault-secrets | Frontend + Backend | Browse and manage HashiCorp Vault secrets |
| terraform-cloud | Frontend + Backend | View TFC workspace status, runs, and state |
| mockup | Frontend | UI mockup and prototyping tools |
| gemini-agent | Frontend + Backend | AI 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:
| Template | Purpose | Target Repository |
|---|---|---|
| create-tenant | Create a new tenant within a business unit | BU repo (PR to terraform/tenants/) |
| create-sandbox-project | Create a standalone sandbox GCP project | Sandbox workspace |
| create-business-unit | Create a new business unit | gcp-foundations-projects |
| edit-tenant-module | Edit an existing tenant's Terraform configuration | BU repo (PR) |
| edit-business-unit | Edit an existing business unit's configuration | BU repo (PR) |
Template Workflow
All templates follow a two-step wizard pattern:
- Basic configuration: User fills in name, description, environment selection, and other high-level parameters
- Terraform module editor: Interactive editor (via
GithubTerraformModuleEditorcustom field) that lets users configure the Terraform module variables with validation - PR creation: The template creates a pull request to the target repository
- 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:
| Field | Purpose | Usage |
|---|---|---|
GithubRepoPicker | Repository selector with org-scoped search | Select target repositories for PRs |
GithubTeamPicker | Team selector with org-scoped search | Assign team permissions to new repos |
GithubTerraformModuleEditor | Interactive Terraform variable editor | Configure 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.jsonfrom 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:
| Standard | Tool | Use Case |
|---|---|---|
| Generic | MkDocs (Material theme) | General-purpose repositories, services, applications |
| Terraform | Docusaurus | Terraform 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
.tffiles - 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:
- Auto-discovers the git context (repo name, org, remote URL)
- Creates the documentation directory structure
- Generates a
catalog-info.yamlfor Backstage registration - Initializes configuration files (
mkdocs.ymlordocusaurus.config.js) - Creates starter documentation pages
End-to-End Self-Service Flow
The typical self-service flow for creating a new tenant:
- Developer opens Backstage portal and selects "Create Tenant" template
- Fills in tenant name, selects business unit, chooses environments
- Uses the Terraform module editor to configure variables
- Template creates a PR to the BU repository's
terraform/tenants/directory - CI runs
terraform planon the PR (with mock credentials) - PR is reviewed and merged
- CI runs
terraform apply, creating the tenant's GCP projects, repo, and workspaces - The new tenant repository appears in Backstage's catalog via
catalog-info.yaml - The tenant team begins using their repository with the foundations-template scaffold