4 min read
On this page

Golden Paths & Templates

A golden path is the recommended way to do something in your organization. It is the paved road that gets you from zero to production with the least friction. Create a service, deploy it, set up monitoring, configure alerts -- each of these should have a golden path that a new engineer can follow on day one.

What a Golden Path Is

The term comes from Spotify, where they described golden paths as "the opinionated and supported path to build something." It is not the only way. It is the easy way. And because it is easy, most teams will follow it.

Golden path for deploying a service:
  1. Push to main branch
  2. CI runs tests automatically
  3. Docker image built and pushed to registry
  4. Staging deployment happens automatically
  5. Run smoke tests against staging
  6. One-click promotion to production

Not a golden path:
  1. SSH into the server
  2. Git pull
  3. Run build script
  4. Restart the process
  5. Hope nothing breaks
  6. Check the logs manually

The golden path encodes institutional knowledge. Instead of asking a senior engineer "how do I deploy this?" for every new service, the answer is in the template and the tooling.

Project Templates

A project template is a starting point for a new service or application. It includes everything a service needs to run in production, baked in from the start.

What a Good Template Includes

# Template structure for a new service
my-service/
  src/                    # Application code scaffold
  Dockerfile              # Container build with multi-stage build
  docker-compose.yml      # Local development environment
  .github/
    workflows/
      ci.yml              # Lint, test, build on every push
      deploy.yml          # Deploy to staging and production
  k8s/
    deployment.yaml       # Kubernetes deployment manifest
    service.yaml          # Kubernetes service manifest
    hpa.yaml              # Horizontal pod autoscaler
  monitoring/
    alerts.yaml           # Prometheus alerting rules
    dashboard.json        # Grafana dashboard
  docs/
    README.md             # Service overview and setup
    runbook.md            # Operational runbook
  .env.example            # Environment variable documentation
  Makefile                # Common commands: build, test, deploy

Template Generation

Templates should be generated programmatically, not copied from a wiki page. Use tools like Cookiecutter, Yeoman, or a custom CLI.

# Example: creating a new service from a template
platform create-service \
  --name payment-processor \
  --language python \
  --framework fastapi \
  --database postgresql \
  --team payments

# Output:
# Created repository: github.com/myorg/payment-processor
# CI/CD pipeline configured
# Kubernetes manifests generated
# Monitoring dashboard created
# Service registered in catalog
# Ready to develop!

The template should produce a service that can deploy to production immediately, even if the only thing it does is return a health check response.

CI/CD Baked In

Every template should come with a working CI/CD pipeline. The developer should never have to configure CI/CD from scratch.

# Example GitHub Actions CI pipeline baked into the template
name: CI
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Lint
        run: make lint

  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Test
        run: make test

  build:
    needs: [lint, test]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Build and push image
        run: make docker-push

Monitoring Baked In

Templates should include monitoring from the start, not as an afterthought.

# Prometheus alerting rules included in the template
groups:
  - name: service-alerts
    rules:
      - alert: HighErrorRate
        expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.05
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "High error rate on {{ $labels.service }}"

      - alert: HighLatency
        expr: histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m])) > 1.0
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "High p99 latency on {{ $labels.service }}"

Service Catalogs

A service catalog is a central registry of every service in your organization. It shows what exists, who owns it, what it depends on, and whether it is healthy.

Service catalog entry for payment-processor:
  Owner:          team-payments
  Language:       Python (FastAPI)
  Dependencies:   user-service, postgres, redis
  Environments:   staging, production
  Deploy status:  Healthy
  Last deploy:    2 hours ago
  On-call:        @payments-oncall
  Documentation:  /docs/payment-processor
  SLO:            99.9% availability, p99 < 500ms

Why Catalogs Matter

Without a catalog, the question "who owns the order-service?" requires asking around on Slack. With a catalog, the answer is one click away. This matters for incident response, architecture reviews, and onboarding.

Without a catalog:
  Incident at 3 AM → who owns this service? → Check git blame →
  That person left the company → Ask in Slack → No response →
  Escalate to engineering manager → 45 minutes wasted

With a catalog:
  Incident at 3 AM → look up service in catalog → team-orders owns it →
  page @orders-oncall → response in 5 minutes

Keeping the Catalog Accurate

The catalog must be accurate or nobody will trust it. The best approach is to make the catalog the source of truth by integrating it with your deployment pipeline.

# catalog-info.yaml lives in the service repo
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: payment-processor
  description: Processes payments and manages transactions
  tags:
    - python
    - fastapi
    - payments
spec:
  type: service
  lifecycle: production
  owner: team-payments
  system: checkout
  providesApis:
    - payments-api
  consumesApis:
    - users-api
  dependsOn:
    - resource:payments-db
    - resource:payments-redis

The Day-One Goal

The ultimate test of your golden paths and templates is this: can a new engineer ship to production on their first day?

Day one for a new engineer:
  9:00  — Laptop set up, accounts provisioned
  9:30  — Clone the service template, run the generator
  10:00 — Local development environment running
  10:30 — Write a small change (update a config, add a field)
  11:00 — Push to main, CI passes
  11:30 — Change is live in staging
  12:00 — Promote to production after review
  12:30 — Lunch, having already shipped to production

This is not a fantasy. Companies with mature platforms achieve this routinely. The key is that the new engineer does not need to understand Kubernetes, Docker networking, CI/CD configuration, or monitoring setup. The golden path handles all of it.

Evolving Templates Over Time

Templates are not static. As your infrastructure evolves, your templates should evolve with it.

Version 1: Basic Dockerfile, GitHub Actions, manual deploy
Version 2: Add Kubernetes manifests, automated staging deploy
Version 3: Add monitoring, alerting, and Grafana dashboards
Version 4: Add OpenTelemetry tracing, service mesh integration
Version 5: Add cost tracking, SLO reporting

The challenge is updating existing services when the template changes. Two approaches:

Approach 1: Template upgrades are manual
  - Announce template changes in a changelog
  - Teams upgrade when they choose
  - Works for small organizations

Approach 2: Automated upgrade PRs
  - A bot detects services using old template versions
  - Opens a PR with the upgrade
  - Team reviews and merges
  - Works for large organizations

Common Pitfalls

  • Templates that are too opinionated -- If the template forces a specific ORM, logging library, and test framework, teams with different needs will reject it; keep opinions where they matter (CI/CD, monitoring, deploy) and leave flexibility where they do not (application code patterns)
  • Templates that rot -- A template that was last updated 18 months ago generates services with outdated dependencies and deprecated patterns; assign ownership and update quarterly
  • No local development story -- The template works in CI but developers cannot run the service locally; always include a docker-compose.yml or equivalent
  • Catalog as a chore -- If updating the catalog requires manual work, it will be out of date within a month; automate catalog updates from the repo and pipeline
  • Golden paths that are actually walls -- If deviating from the golden path requires filing a ticket and waiting three days, it is not a golden path, it is a mandate; developers must be able to step off the path when they need to
  • Skipping documentation -- Templates without README files and runbooks produce services that only the original author understands

Key Takeaways

  • A golden path is the recommended, supported way to do something -- not enforced, but the easiest option
  • Project templates should include CI/CD, Docker, monitoring, and alerting from the start
  • A service catalog is a central registry that answers "who owns this?" and "what depends on what?"
  • The ultimate goal: a new engineer ships to production on day one
  • Templates must evolve over time; stale templates produce stale services
  • Make the right thing the easy thing and most teams will do the right thing