What Golden Paths Are#

A golden path is a pre-built, opinionated workflow that gets a developer from zero to a production-ready artifact with minimal decisions. The term comes from Spotify’s internal platform work. Netflix calls them “paved roads.” The idea is the same: provide a well-maintained, well-tested default path that handles 80% of use cases, while allowing teams to go off-road when they have legitimate reasons.

A golden path is not a mandate. It is a recommendation backed by automation. Create a new Go microservice using the golden path and you get a repository with CI/CD, Kubernetes manifests, observability, and a Backstage catalog entry — working in minutes. The golden path removes the 40+ decisions a developer would otherwise need to make.

Opinionated vs Flexible#

The most common mistake is making golden paths too flexible. Every decision point you add is friction. Every “choose your own” option is a maintenance burden for the platform team.

Opinionated choices that work well:

  • One language runtime per template: A Go service template, a Python service template, a TypeScript service template. Not a polyglot template with a language picker.
  • One CI system: The template uses GitHub Actions or Jenkins. Not both.
  • One deployment target: Kubernetes via ArgoCD. Not “choose between ECS, Lambda, or Kubernetes.”
  • One observability stack: OpenTelemetry to your existing backend. Pre-wired, not optional.

Where flexibility is warranted:

  • Service name and team ownership (obviously).
  • Database selection from a pre-approved list (PostgreSQL, Redis, DynamoDB).
  • Public vs internal API exposure.
  • Resource sizing (small/medium/large presets, not arbitrary CPU/memory values).

A good rule: if fewer than 20% of users would change a default, hardcode it. If a decision genuinely varies by team, offer 2-3 pre-validated options. Never offer a free-text field where a dropdown will do.

Designing a New Service Golden Path#

A production-ready golden path for a new microservice typically produces:

  1. A Git repository with the application skeleton, Dockerfile, Makefile, and README.
  2. CI pipeline configuration — build, test, lint, container image push.
  3. Kubernetes manifests — Deployment, Service, Ingress, HPA, PodDisruptionBudget, NetworkPolicy. Preferably via Helm chart with sane defaults.
  4. Observability wiring — Prometheus metrics endpoint, structured logging, OpenTelemetry tracing initialization.
  5. Backstage catalog entrycatalog-info.yaml with component metadata, ownership, and API definitions.
  6. GitOps registration — ArgoCD Application manifest or entry in an ApplicationSet generator source.

Example output structure for a Go service:

my-service/
  cmd/server/main.go
  internal/handler/health.go
  Dockerfile
  Makefile
  .github/workflows/ci.yaml
  deploy/
    helm/
      Chart.yaml
      values.yaml
      values-staging.yaml
      values-production.yaml
      templates/
        deployment.yaml
        service.yaml
        ingress.yaml
  catalog-info.yaml
  docs/
    index.md

New Database Golden Path#

Not all golden paths produce services. A database golden path provisions infrastructure:

  1. Developer selects “New PostgreSQL Database” from the platform catalog.
  2. Template prompts for: database name, owning team, environment, size preset (small: 2 vCPU/4GB, medium: 4 vCPU/16GB, large: 8 vCPU/32GB).
  3. Template generates a Crossplane Claim or Terraform module invocation in a GitOps repository.
  4. ArgoCD syncs the claim. Crossplane provisions an RDS instance (or CloudNativePG cluster for in-cluster).
  5. Connection credentials are written to a Kubernetes Secret or external secret store.
  6. The catalog entry is created, linking the database resource to the owning team and consuming services.
# crossplane-claim generated by the golden path
apiVersion: database.platform.example.com/v1alpha1
kind: PostgreSQLInstance
metadata:
  name: orders-db
  namespace: team-commerce
spec:
  parameters:
    size: medium
    version: "16"
    backup:
      enabled: true
      retentionDays: 30
  compositionSelector:
    matchLabels:
      provider: aws
      environment: production
  writeConnectionSecretToRef:
    name: orders-db-credentials

Backstage Software Templates#

Backstage’s Scaffolder is the most common implementation vehicle. Templates are defined in YAML with a template.yaml spec:

apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
  name: go-microservice
  title: Go Microservice
  description: Production-ready Go service with CI/CD and Kubernetes deployment
spec:
  owner: platform-team
  type: service
  parameters:
    - title: Service Details
      required: [name, owner]
      properties:
        name:
          type: string
          pattern: '^[a-z][a-z0-9-]{2,30}$'
        owner:
          type: string
          ui:field: OwnerPicker
        description:
          type: string
  steps:
    - id: fetch
      name: Fetch Skeleton
      action: fetch:template
      input:
        url: ./skeleton
        values:
          name: ${{ parameters.name }}
          owner: ${{ parameters.owner }}
    - id: publish
      name: Create Repository
      action: publish:github
      input:
        repoUrl: github.com?owner=myorg&repo=${{ parameters.name }}
        defaultBranch: main
    - id: register
      name: Register in Catalog
      action: catalog:register
      input:
        repoContentsUrl: ${{ steps.publish.output.repoContentsUrl }}
        catalogInfoPath: /catalog-info.yaml

The skeleton/ directory contains the actual template files with Nunjucks-style variable substitution. When a developer fills in the form and clicks “Create,” Backstage executes each step sequentially.

Alternatives to Backstage Scaffolder#

Cookiecutter remains widely used, especially for teams that do not run Backstage. Templates are Jinja2-based and triggered from the CLI:

cookiecutter gh:myorg/service-template \
  --no-input \
  service_name=order-service \
  team=commerce

Cookiecutter is simpler but lacks the UI, catalog integration, and multi-step orchestration that Backstage provides. It is a good starting point for teams not ready for a full developer portal.

Yeoman is Node.js-based with interactive prompts and composable generators. More powerful than Cookiecutter for complex scaffolding but steeper learning curve.

Proton by AWS offers golden path templates for AWS-native stacks with built-in provisioning. Useful if fully committed to AWS but vendor-locked.

Measuring Adoption#

Golden paths only work if people use them. Track these metrics:

  • Template usage rate: How many new services/resources were created via golden paths vs manually? Target 80%+ adoption within 6 months.
  • Time to first deploy: How long from “I need a new service” to “it runs in staging”? Golden paths should reduce this from days to under 30 minutes.
  • Drift from template: How many golden-path-created services diverged from the template’s patterns? High drift signals the template is missing real needs.
  • Template satisfaction: Quarterly survey asking “Did the template give you what you needed? What was missing?”

Instrument with Backstage analytics plugins, CI pipeline metadata, or a tracking table recording which template produced each repository. Golden paths are not static artifacts — they are products. Maintain them like production services: versioned, tested, and iterated based on user feedback.