Engineering5 min read

Platform Engineering Without a Platform Team: Golden Paths for Small Organisations

You don't need a platform team or a developer portal to get most of the benefits of platform engineering. For small organisations I focus on a few golden paths: a service template, shared CI, shared Terraform modules and a catalogue that lives in the repositories.

Gopal Yendluri
Contents
  1. The Problem Platform Engineering Solves
  2. What a Golden Path Is (and Isn't)
  3. The Four Paths That Matter Most
  4. When a Developer Portal Is Worth It
  5. Avoiding the Internal Product Nobody Asked For
  6. What to Do by Stage
  7. The Takeaway

The Problem Platform Engineering Solves

Platform engineering has become the default answer to a real problem: every team building services slightly differently. Different CI pipelines, different logging, different ways of handling secrets, different Terraform. Each difference is small. Together they make every new service slower to build, every incident harder to debug and every security fix a project across a dozen repositories.

The industry's answer, often, is a platform team and an internal developer portal. That works at scale. In a small organisation, with perhaps two to six product teams, you can't justify a dedicated team, and you certainly can't justify running a portal nobody asked for.

The good news is that most of the value comes from a handful of golden paths, not from the portal.

What a Golden Path Is (and Isn't)

A golden path is the supported, documented, easiest way to do a common thing: create a service, deploy it, add a queue, provision a database. It is not a mandate. Teams can step off it, but they then own the consequences, and the path should be good enough that they rarely want to.

The test I use: a new engineer should be able to go from "we need a new service" to "it's deployed to staging with logs, metrics and alerts" in a day, without asking anyone which way is right.

The Four Paths That Matter Most

1. A Service Template

Start with a template repository that encodes your decisions: folder structure, linting, test setup, Dockerfile, health check endpoint, structured logging, error reporting, a standard README. GitHub template repositories are enough to start. If you need parameters (service name, owning team, whether it needs a queue), Cookiecutter or Copier generate a project from a template with prompts.

The trap is that a template is a snapshot. Services created from it drift as the template improves. Copier helps here because it can apply template updates to existing projects, but in practice I keep templates thin and put the shared behaviour in libraries and reusable pipelines, which update centrally.

2. Paved-Road CI/CD

Shared pipelines give you more consistency per hour of effort than anything else. With GitHub Actions, reusable workflows let every repository call a central definition:

# .github/workflows/ci.yml in a service repository
name: CI
on:
  pull_request:
  push:
    branches: [main]
 
jobs:
  build:
    uses: our-org/platform-workflows/.github/workflows/node-service.yml@v3
    with:
      node-version: "22"
      deploy-environment: staging
    secrets: inherit

The central workflow handles install, tests, security scanning, image build and deployment. Version it with tags so teams upgrade deliberately, and keep the inputs few. Every input is a decision you've pushed back to the team.

3. Shared Terraform Modules

Infrastructure is where divergence costs most. A small set of opinionated modules (a queue with its dead-letter queue and alarms, a Lambda worker, a service with its load balancer and dashboards) captures the decisions you want everyone to make the same way.

module "orders_queue" {
  source = "git::https://github.com/our-org/terraform-modules.git//sqs-worker-queue?ref=v2.4.0"
 
  name               = "orders"
  max_receive_count  = 5
  alarm_topic_arn    = var.alerts_topic_arn
  tags               = local.tags
}

Pin module versions with ref, publish a changelog, and resist the urge to expose every argument of the underlying resources. A module with forty variables is just the AWS provider with extra steps. When I wrote about moving async work onto SQS, this was the pattern that made it cheap to add each new queue consistently.

4. A Lightweight Service Catalogue

You need to know what services exist, who owns them, where they run and how to get to their dashboards and runbooks. You don't need a portal to answer that.

Start with a catalog-info.yaml file in each repository. I use the Backstage entity format even without Backstage, because it is well documented and means the data is ready if you adopt a portal later.

apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: orders-service
  description: Order creation and status transitions
  annotations:
    github.com/project-slug: our-org/orders-service
  links:
    - url: https://example.com/dashboards/orders
      title: Dashboard
    - url: https://example.com/runbooks/orders
      title: Runbook
spec:
  type: service
  lifecycle: production
  owner: team-fulfilment
  system: subscriptions

A small script that collects these files across the organisation and generates a single page is enough for a surprisingly long time.

When a Developer Portal Is Worth It

Backstage is powerful and free to use, but it is a framework you build and run, not a product you install. It needs people who are comfortable maintaining a React and Node.js application and its plugins. Hosted portals such as Port, Cortex and OpsLevel reduce the running cost but add a licence.

Signal Catalogue files and templates Developer portal
Number of services Dozens Many dozens to hundreds
Number of teams A handful Many, with frequent reorganisation
Main pain Inconsistent setup Discoverability, ownership, scorecards
Who maintains it Engineers part-time Someone with dedicated time
Self-service needs Templates and pipelines Workflows across many systems

My rule: adopt a portal when finding things and tracking ownership has become the bottleneck, not when setting things up is. The portal is a front end. If the golden paths behind it aren't good, it just gives you a nicer way to find inconsistent services.

Avoiding the Internal Product Nobody Asked For

The most common failure I see is a platform built from the platform builder's point of view. It abstracts things teams didn't find hard, and ignores the things they did.

  • Start with pain, not architecture. Ask teams what slowed their last three pieces of work. Build for the most common answer.
  • Treat it as a product. Even without a platform team, someone should own each golden path, with a changelog and a way to report problems.
  • Make the path easier than the alternative. If using the template takes longer than copying an old service, people will copy the old service.
  • Build the thinnest thing that works. A documented Terraform module and a README is a platform. So is a shell script, if it solves the problem.
  • Measure adoption. If a golden path isn't being used, that is feedback about the path.

What to Do by Stage

Stage Focus
Startup (one or two teams) One service template, one reusable pipeline, conventions written in a README.
Small scaleup (three to six teams) Shared Terraform modules, catalogue files in every repository, a rotating owner for each golden path.
Larger scaleup and beyond A platform team with product ownership, and a portal once discoverability is the problem.

The Takeaway

For a small organisation, platform engineering means a few well-maintained golden paths rather than a platform team: a service template, reusable CI/CD, shared Terraform modules and a catalogue file in every repository. Build them from real developer pain, keep them thin, and only reach for a developer portal when finding and owning things, not creating them, has become the bottleneck.

platform-engineeringgolden-pathsdeveloper-experienceTerraformCI-CDBackstage