OrchStep for platform engineers
Golden paths only stay golden if every team runs the same steps. Here's how to ship a paved-road scaffold and onboarding as OrchStep workflows app teams run themselves — versioned, previewable, and reusable across repos.
blog/platform-golden-pathsYou build the paved road. The problem is keeping anyone on it. You write a beautiful "creating a new service" doc, and three months later every team has a slightly different layout, a config file that drifted, and a Slack thread asking how to register a service in the catalog. The golden path is a wiki page, and wiki pages don't execute.
The fix isn't more documentation. It's making the paved road a thing teams run instead of read — a scaffold and an onboarding flow that produce the same result every time, that you version, and that an app developer can preview before they trust it.
This post turns two platform workflows into OrchStep: new-service (scaffold, render the standard config, register in the catalog) and onboard (install the toolchain, verify the environment). Same generators and CLIs your golden path already uses — packaged so the path is self-service, not a ticket to your team.
The pain, concretely
- "How do I create a new service?" is a recurring question because the answer is prose.
- Every team's config drifts from the template because the template is copy-paste.
- Onboarding a new hire means someone on the platform team walks them through it.
The workflows
new-service scaffolds the repo, uses func: render to produce the standard config from variables (so it's generated, not pasted), captures it as an output, and registers it. onboard installs the toolchain and verifies the environment with retries. App teams run these directly; you own the definition.
name: paved-road
defaults:
service_name: "new-svc"
team: payments
tasks:
# `orchstep run new-service --var service_name=billing --var team=payments`
new-service:
steps:
- name: scaffold
func: shell
do: echo "scaffolding {{ vars.service_name }} for team {{ vars.team }}"
- name: config
func: render
args:
template: "service {{ vars.service_name }} owned by {{ vars.team }}"
outputs:
manifest: "{{ result.output }}"
- name: register
func: shell
do: echo "registering {{ steps.config.manifest }} in catalog"
# `orchstep run onboard`
onboard:
steps:
- name: tools
func: shell
do: echo "installing toolchain for {{ vars.team }}"
- name: checks
func: shell
do: echo "verifying environment for {{ vars.team }}"
retry:
max_attempts: 3
interval: "1s"
backoff_rate: 2.0The config step renders the standard manifest from variables instead of asking teams to copy a template — so there's nothing to drift. It captures the result as an output the register step consumes, so "scaffold" and "register" can't disagree about what was created. When the golden path changes, you change one workflow, not every team's copy.
Make it self-service
orchstep run new-service --var service_name=billing --var team=paymentsAn app developer runs that and gets a service that matches the standard, every field filled from named variables. They don't need to know the internals — and they don't need a ticket. To discover what's available:
orchstep menuThe picker lists every paved-road task with hotkeys. As your golden path matures, factor shared pieces into reusable modules so multiple workflows pull from one versioned source instead of forking.
Let teams preview before they trust it
Adoption depends on trust, and nobody trusts a generator they can't inspect. A dry-run resolves the variables and prints exactly what new-service will scaffold and register — without creating anything:
orchstep run new-service --var service_name=billing --var team=payments --dry-runA skeptical team reads the plan, sees it's sane, and opts in. More in Previewing with Dry Run.
What you actually gained
| Concern | Wiki golden path | OrchStep |
|---|---|---|
| "How do I create a service?" | a doc, often stale | orchstep run new-service |
| Config drift | copy-paste templates | func: render generates it |
| Scaffold vs register mismatch | two manual steps | one output feeds the next |
| Onboarding | platform team walkthrough | orchstep run onboard |
| Updating the path | edit every team's copy | edit one versioned workflow |
This isn't an internal developer platform with a UI and a control plane — if you're running Backstage or similar, this is the executable layer underneath the buttons. OrchStep gives the paved road a runnable shape that app teams invoke and you maintain in one place. Where a single command already is the golden path, leave it. The multi-step scaffolds and onboarding flows are where drift hides, and where this pays off.
Where to go next
- Quick Start — your first workflow in two minutes
- Modules — reusable, versioned pieces shared across workflows
- Composition — building tasks from tasks
- Service Scaffolding — a worked golden-path example
Tired of answering "how do I make a new service?" Turn the answer into orchstep run new-service.
curl -fsSL https://orchstep.dev/install.sh | sh