Service Onboarding Automation

Service onboarding automation turns a developer’s “I need a new service” — or a new hire’s first day — into a deterministic, auditable sequence that ends with a productive, cataloged result instead of a week of manual ticket-chasing.

This sub-section of Developer Experience & Self-Service Platforms covers the orchestration layer: chaining repository scaffolding, CI bootstrap, infrastructure provisioning, catalog registration, and access grants into a single self-service flow. The automation engine is the Backstage scaffolder, and the action sequencing builds directly on Scaffolder Template Design.

Onboarding pipeline from a portal form to a registered service with access granted A portal intake form triggers repository creation, CI bootstrap, catalog registration, and an access grant, each step passing outputs to the next. Intake Form parameters Create Repo publish:github Bootstrap CI + IaC Register catalog entity Grant access
Each onboarding step consumes the previous step's output, producing a fully wired service.

Prerequisites & Environment Baseline

Onboarding can only run end-to-end when four things exist: the scaffolder with provider modules, scoped credentials for each provider, catalog group ownership for access grants, and an RBAC policy over who may run the template.

Prerequisites for onboarding automation The scaffolder with provider modules, scoped credentials, catalog group ownership, and RBAC enable onboarding. scaffolder modules scoped credentials group ownership RBAC policy Onboarding runs auditable chain
Per-provider scoped credentials keep one onboarding run from holding more access than the task requires.
  • Scaffolder backend: @backstage/plugin-scaffolder-backend@^1.22.0 plus @backstage/plugin-scaffolder-backend-module-github@^0.5.0 for repository actions.
  • Provider credentials via env: ${GITHUB_TOKEN} (repo + workflow scopes), ${ARGOCD_AUTH_TOKEN} for deployment registration, and ${VAULT_TOKEN} for secret namespace creation. Inject these through app-config.yaml, never inline.
  • Catalog with group ownership: Access grants resolve teams from Group entities; ensure your identity provider sync populates them.
  • An RBAC policy: Decide which groups may run the onboarding template, consistent with your Team Permission Models.
  • CLI toolchain: @backstage/cli@^0.27.0 for dry-run and validation.

Step-by-Step Configuration & Plugin Architecture

The design principle is minimal intake, maximal default: a short form captures only what cannot be defaulted, the golden path supplies the rest, and the same engine runs two templates — one for services, one for people.

Minimal intake, defaulted rest, two templates A short intake form plus golden-path defaults feed one engine running a service template and a people template. Minimal form name · owner · system Engine + defaults scaffolder Service template People template
One engine, two templates keeps the audit trail and RBAC model identical for service and engineer onboarding.

1. Capture intent in a minimal form

The intake form should collect only what cannot be defaulted. Everything else is supplied by the golden path.

# templates/onboarding.yaml
# Requires scaffolder.backstage.io/v1beta3 (Backstage >= 1.22.0)
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
  name: service-onboarding
  title: Onboard a New Service
spec:
  owner: group:platform-engineering
  type: service
  parameters:
    - title: Service basics
      required: [name, owner, system]
      properties:
        name: { title: Service name, type: string, pattern: "^[a-z][a-z0-9-]{2,38}$" }
        owner:
          title: Owning team
          type: string
          ui:field: OwnerPicker
          ui:options: { catalogFilter: { kind: Group } }
        system: { title: Parent system, type: string, ui:field: EntityPicker }

2. Chain the provisioning steps

Sequence actions so each consumes the prior step’s output. Repository scaffolding is covered in depth in Automating Repository Scaffolding with Backstage Software Templates.

  steps:
    - id: scaffold
      name: Render service files
      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=${GITHUB_ORG}&repo=${{ parameters.name }}
        defaultBranch: main
        protectDefaultBranch: true

    - id: register
      name: Register in catalog
      action: catalog:register
      input:
        repoContentsUrl: ${{ steps.publish.output.repoContentsUrl }}
        catalogInfoPath: /catalog-info.yaml

3. Separate human onboarding from service onboarding

People onboarding reuses the same engine but provisions accounts, group memberships, and access rather than repositories — covered in Onboarding New Engineers with Self-Service Workflows.

Validation is short but non-negotiable: the template must schema-validate, and a dry-run must produce a catalog-info.yaml whose owner resolves to a real group — a service with no owner is worse than no service.

Onboarding template validation Schema validation and a dry-run whose output resolves a group owner confirm the onboarding template. Schema validate 0 errors Dry-run output rendered Owner resolves group: prefix
An unresolved owner in the dry-run means the produced service would be un-ownable — fail the pipeline on it.
# Validate and dry-run the onboarding template
# Requires @backstage/cli >= 0.27.0
set -euo pipefail
npx @backstage/cli catalog validate --path ./templates/onboarding.yaml
# expected: "Validated 1 entity ... 0 errors"

After a dry-run, confirm the generated entity resolves an owner:

yq '.spec.owner' ./dry-run-output/catalog-info.yaml | grep -qE '^group:' && echo "owner resolved"
# expected: "owner resolved"

Maintenance & Lifecycle Management

Maintenance treats the onboarding flow as a production service: pinned provider modules, a nightly end-to-end smoke test, a cleanup path for partial runs, and success-rate metrics.

Onboarding flow maintenance Pinned modules, a nightly smoke test, a cleanup path for partial runs, and success-rate metrics keep onboarding reliable. Pin modules exact versions Nightly smoke throwaway org Cleanup path partial runs Success metrics TTFC + rate
The cleanup path matters because a half-failed run leaves a partial repo; idempotent steps let the run simply be retried.
  • Upgrade path: Pin provider modules and bump them in lockstep with provider API deprecations; run the nightly end-to-end onboarding smoke test against a throwaway org before promoting a new module version.
  • Rollback: On a failed onboarding run, the scaffolder leaves a partial repository. Provide a cleanup task (gh repo delete, catalog entity removal) and make onboarding steps idempotent where possible.
  • Debug commands: LOG_LEVEL=debug surfaces each action’s input and output, which is the fastest way to find where a chain breaks.
  • Metrics: Track time-to-first-commit and onboarding success rate via Developer Experience Metrics.

Common Pitfalls & Mitigation Strategies

The onboarding pitfalls split into reliability failures (non-idempotent steps, orphaned entities) and governance failures (sync approvals, broad tokens). The diagram groups the four so the fix is either an idempotency guard or a policy control.

Onboarding pitfalls by class Non-idempotent steps and orphaned entities are reliability failures; sync approvals and broad tokens are governance failures. Reliability non-idempotent orphaned entity → guard + register last Governance sync approvals broad tokens → async + scoped
Idempotent steps plus scoped, delegated identity make a run safe to retry and safe to audit.
  • Non-idempotent steps. Root cause: actions that fail if the repository already exists. Fix: guard with existence checks and make retries safe so a half-failed run can be re-run.
  • Synchronous human approvals. Root cause: a manager-approval gate embedded mid-flow. Fix: move approvals to asynchronous policy and notify, rather than blocking the pipeline.
  • Broad service tokens. Root cause: one powerful token for all actions. Fix: scope tokens per action and pass the requesting user’s identity where supported.
  • Orphaned catalog entities. Root cause: registration succeeding after a later step fails. Fix: register last, or reconcile periodically against the source repository.

Frequently Asked Questions

Should onboarding provision infrastructure directly or open a request to a platform pipeline?

For low-risk, well-bounded resources (a repository, a CI pipeline, a namespace) provision directly within the onboarding flow so the developer gets a complete result. For high-blast-radius resources (production databases, networking) emit a declarative request that a separate platform pipeline reconciles, keeping ownership of risky changes with the platform while still giving the developer a single self-service entry point.

How do we keep onboarding flows from drifting as provider APIs change?

Pin every provider module to an exact version, run a scheduled end-to-end smoke test against a disposable target, and treat the onboarding template like any other production service with its own CI and on-call. Drift surfaces in the smoke test long before a real developer hits it.

Can the same flow onboard both services and engineers?

Use one engine, two templates. Service onboarding produces repositories and catalog entities; engineer onboarding produces accounts, group memberships, and access grants. Sharing the scaffolder keeps the execution surface, audit trail, and RBAC model consistent across both.