Back to Blog

Platform Engineering: Internal Developer Platforms, Backstage, and Golden Paths

Build an internal developer platform — Backstage service catalog setup, golden path templates, self-service infrastructure, platform team organization, and meas

Viprasol Tech Team
May 9, 2026
13 min read

Platform Engineering: Internal Developer Platforms, Backstage, and Golden Paths

Platform engineering is the discipline of building internal products for developers — the infrastructure, tooling, and workflows that allow application teams to ship faster without each team reinventing deployment pipelines, observability, and service scaffolding.

The core concept: treat developers as customers. Build a product (the Internal Developer Platform, or IDP) that makes the right way to do things also the easy way.


When Platform Engineering Makes Sense

Platform teams make sense when you have:

  • 50+ engineers spending time on infrastructure and DevOps concerns instead of product
  • 5+ application teams each building their own CI/CD pipelines, monitoring, and deployment tooling
  • Repeated patterns across services (every team sets up the same Dockerfile, GitHub Actions workflow, alerting rules)
  • Cognitive load from infrastructure slowing feature delivery

For smaller organizations: a well-documented set of templates and runbooks achieves most of the benefit without a dedicated platform team.


The Internal Developer Platform Stack

A mature IDP typically includes:

LayerWhat It ProvidesCommon Tools
Service catalogInventory of all services with owners, docs, pipelinesBackstage, OpsLevel, Cortex
Golden path templatesOpinionated scaffolding for new servicesBackstage Software Templates, Cookiecutter
CI/CDStandardized pipelines teams can extendGitHub Actions (shared workflows), Tekton
Infrastructure self-serviceProvision databases, queues, storage without ticketsCrossplane, Terraform Cloud, Pulumi
ObservabilityPre-configured dashboards, alerts, log aggregationGrafana, Datadog, OpenTelemetry
Secret managementSecrets without Slack messagesVault, AWS SSM, External Secrets Operator
EnvironmentsOn-demand ephemeral environments for PRsNamespace-per-PR, Preview environments

☁️ Is Your Cloud Costing Too Much?

Most teams overspend 30–40% on cloud — wrong instance types, no reserved pricing, bloated storage. We audit, right-size, and automate your infrastructure.

  • AWS, GCP, Azure certified engineers
  • Infrastructure as Code (Terraform, CDK)
  • Docker, Kubernetes, GitHub Actions CI/CD
  • Typical audit recovers $500–$3,000/month in savings

Backstage: The Service Catalog

Backstage (Spotify, open-source) is the most widely adopted IDP framework. It provides a service catalog, software templates, and a plugin ecosystem.

Install and configure Backstage:

npx @backstage/create-app@latest
cd my-backstage-app
yarn dev  # Starts at http://localhost:3000

Register a service in the catalog:

# catalog-info.yaml — in every service repository
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: payment-service
  description: Handles all payment processing  Stripe integration, webhooks, refunds
  annotations:
    github.com/project-slug: yourorg/payment-service
    backstage.io/techdocs-ref: dir:.
    pagerduty.com/service-id: P12345
    datadog/dashboard-url: https://app.datadoghq.com/dashboard/xxx
  tags:
    - typescript
    - payments
    - critical
  links:
    - url: https://payment-service.internal.yourapp.com/health
      title: Health Check
    - url: https://grafana.yourapp.com/d/payment
      title: Grafana Dashboard
spec:
  type: service
  lifecycle: production
  owner: payments-team
  system: billing
  dependsOn:
    - resource:default/payments-postgres
    - resource:default/stripe-api
  providesApis:
    - payment-api

Backstage Software Template (Golden Path):

# templates/typescript-service/template.yaml
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
  name: typescript-microservice
  title: TypeScript Microservice
  description: Create a new TypeScript service with Fastify, PostgreSQL, and CI/CD pre-configured
  tags: [typescript, fastify, postgresql]
spec:
  owner: platform-team
  type: service

  parameters:
    - title: Service Information
      required: [name, description, owner]
      properties:
        name:
          type: string
          pattern: '^[a-z][a-z0-9-]*$'
          description: Service name (kebab-case)
        description:
          type: string
        owner:
          type: string
          ui:field: OwnerPicker
          ui:options:
            allowedKinds: [Group]
        needsDatabase:
          type: boolean
          default: false
          title: Include PostgreSQL database?

  steps:
    - id: fetch-template
      name: Fetch Template
      action: fetch:template
      input:
        url: ./skeleton
        values:
          name: ${{ parameters.name }}
          description: ${{ parameters.description }}
          owner: ${{ parameters.owner }}
          needsDatabase: ${{ parameters.needsDatabase }}

    - id: create-repo
      name: Create GitHub Repository
      action: github:repo:create
      input:
        repoUrl: github.com?repo=${{ parameters.name }}&owner=yourorg
        defaultBranch: main
        topics: [typescript, microservice]

    - id: push-to-repo
      name: Push to Repository
      action: github:repo:push
      input:
        repoUrl: github.com?repo=${{ parameters.name }}&owner=yourorg
        defaultBranch: main

    - id: register-catalog
      name: Register in Catalog
      action: catalog:register
      input:
        repoContentsUrl: https://github.com/yourorg/${{ parameters.name }}/blob/main
        catalogInfoPath: /catalog-info.yaml

  output:
    links:
      - title: View in Backstage
        entityRef: ${{ steps.register-catalog.output.entityRef }}
      - title: GitHub Repository
        url: ${{ steps.create-repo.output.remoteUrl }}

What the generated skeleton includes:

skeleton/
├── .github/
│   └── workflows/
│       └── ci.yml          ← Pre-configured CI pipeline
├── src/
│   ├── app.ts              ← Fastify server setup
│   ├── config.ts           ← Zod config validation
│   └── routes/
│       └── health.ts       ← Liveness + readiness probes
├── ${% if values.needsDatabase %}
├── prisma/
│   └── schema.prisma       ← PostgreSQL schema
${% endif %}
├── Dockerfile              ← Multi-stage, non-root user
├── catalog-info.yaml       ← Auto-registered in Backstage
├── terraform/              ← ECS task definition, IAM roles
└── README.md               ← Generated from template

Golden Path CI/CD (Reusable GitHub Actions)

Instead of every team writing their own GitHub Actions workflow, provide shared workflows:

# .github/workflows/shared-build-push.yml
# Published in your platform org: yourorg/platform-workflows

name: Build and Push Docker Image

on:
  workflow_call:
    inputs:
      service-name:
        required: true
        type: string
      dockerfile:
        required: false
        type: string
        default: './Dockerfile'
    secrets:
      aws-role-arn:
        required: true

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read

    steps:
      - uses: actions/checkout@v4

      - name: Configure AWS credentials (OIDC)
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.aws-role-arn }}
          aws-region: us-east-1

      - name: Login to ECR
        uses: aws-actions/amazon-ecr-login@v2

      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          push: true
          tags: |
            ${{ env.ECR_REGISTRY }}/${{ inputs.service-name }}:${{ github.sha }}
            ${{ env.ECR_REGISTRY }}/${{ inputs.service-name }}:latest
          cache-from: type=gha
          cache-to: type=gha,mode=max
# Service team's workflow — 10 lines instead of 80
name: CI

on:
  push:
    branches: [main]

jobs:
  build:
    uses: yourorg/platform-workflows/.github/workflows/shared-build-push.yml@main
    with:
      service-name: payment-service
    secrets:
      aws-role-arn: ${{ secrets.AWS_ROLE_ARN }}

⚙️ DevOps Done Right — Zero Downtime, Full Automation

Ship faster without breaking things. We build CI/CD pipelines, monitoring stacks, and auto-scaling infrastructure that your team can actually maintain.

  • Staging + production environments with feature flags
  • Automated security scanning in the pipeline
  • Uptime monitoring + alerting + runbook automation
  • On-call support handover docs included

Self-Service Infrastructure with Crossplane

Crossplane lets application teams provision cloud resources (databases, queues, storage) via Kubernetes CRDs — without writing Terraform or opening tickets to the platform team:

# Application team creates this in their namespace
# Platform team's Crossplane compositions handle the actual provisioning
apiVersion: database.platform.yourorg.com/v1alpha1
kind: PostgreSQLInstance
metadata:
  name: payment-db
  namespace: payments-team
spec:
  parameters:
    size: small       # Platform translates to RDS instance type
    storage: 20       # GB
    environment: production
    backupRetentionDays: 14
  writeConnectionSecretsToRef:
    name: payment-db-creds  # Secret auto-created in team namespace

The platform team defines what "small" means (db.t3.small), what backup retention they require, which VPC it deploys to — application teams just say what they need.


Measuring Platform Impact

-- Track time engineers spend on infrastructure vs product
-- (Survey data + ticket data from your ticketing system)

SELECT
    month,
    AVG(infra_ticket_hours) AS avg_hours_on_infra,
    AVG(product_ticket_hours) AS avg_hours_on_product,
    ROUND(AVG(infra_ticket_hours) / NULLIF(AVG(infra_ticket_hours + product_ticket_hours), 0) * 100, 1)
      AS pct_time_on_infra
FROM engineering_time_tracking
GROUP BY month
ORDER BY month;

-- Target: < 10% of engineering time on infrastructure concerns
-- (vs. industry average of 20-30% without a platform team)

Key platform metrics:

  • Time to first deployment for new services (Golden Path target: < 1 day, from idea to running in staging)
  • Cognitive load score (quarterly survey: "How confident are you that you understand how to deploy your service?")
  • Infrastructure ticket volume (should decrease as self-service matures)
  • MTTR (platform's contribution to faster incident response via standardized observability)

Working With Viprasol

We build internal developer platforms for engineering organizations — Backstage deployment and customization, golden path templates, shared CI/CD workflows, and self-service infrastructure with Crossplane or Terraform Cloud. Platform engineering pays for itself by removing DevOps bottlenecks that slow every team.

Talk to our platform team about building your internal developer platform.


See Also

Share this article:

About the Author

V

Viprasol Tech Team

Custom Software Development Specialists

The Viprasol Tech team specialises in algorithmic trading software, AI agent systems, and SaaS development. With 100+ projects delivered across MT4/MT5 EAs, fintech platforms, and production AI systems, the team brings deep technical experience to every engagement. Based in India, serving clients globally.

MT4/MT5 EA DevelopmentAI Agent SystemsSaaS DevelopmentAlgorithmic Trading

Need DevOps & Cloud Expertise?

Scale your infrastructure with confidence. AWS, GCP, Azure certified team.

Free consultation • No commitment • Response within 24 hours

Viprasol · Big Data & Analytics

Making sense of your data at scale?

Viprasol builds end-to-end big data analytics solutions — ETL pipelines, data warehouses on Snowflake or BigQuery, and self-service BI dashboards. One reliable source of truth for your entire organisation.