The "Blank Page" Problem
Starting a new project is surprisingly hard. A developer needs to:
- Create a Git repository with the right naming convention.
- Set up the basic framework code (e.g., a Spring Boot skeleton).
- Configure CI/CD pipelines (e.g., GitHub Actions YAML files).
- Write a Dockerfile using the company's approved secure base image.
- Create Kubernetes manifests with resource limits and health checks.
- Hook up monitoring, logging, and alerting.
- Register the service in the Software Catalog.
Usually, developers solve this by finding an old project and copy-pasting the configuration. This leads to configuration drift — bad practices, outdated base images, and deprecated API versions get copied around forever. A security vulnerability fixed in one service's Dockerfile never gets propagated to the 40 services that copied it.
Software Templates (Scaffolding)
Backstage uses Software Templates to solve this. A template is a YAML definition that describes a form (inputs) and a series of automated steps (actions) to execute when the form is submitted.
A developer goes to the portal, clicks "Create New Service," and selects a template like "Java Spring Boot Microservice." They fill out a simple form:
- Service Name:
inventory-service - Owner Team:
team-supply - Slack Alert Channel:
#alerts-team-supply
The portal takes those inputs and automatically:
- Creates a new GitHub repository named
inventory-service. - Populates it with a fully working Spring Boot skeleton.
- Adds a
Dockerfileusing the company's approved base image. - Adds a
.github/workflows/deploy.yamlCI/CD pipeline. - Adds a
catalog-info.yamlpre-filled with the owner and service name. - Registers the new service in the Software Catalog.
The developer can start writing feature code on day one, minute one. Every new service starts from the same secure, compliant baseline.
Here is a simplified Software Template definition showing the structure:
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: java-spring-boot-service
title: Java Spring Boot Microservice
description: Creates a new production-ready Spring Boot service.
spec:
owner: group:platform-team
type: service
parameters:
- title: Service Details
required: [serviceName, owner, slackChannel]
properties:
serviceName:
title: Service Name
type: string
description: Unique name for the service (e.g., inventory-service)
owner:
title: Owner Team
type: string
ui:field: OwnerPicker
slackChannel:
title: Slack Alert Channel
type: string
steps:
- id: fetch-template
name: Fetch Base Template
action: fetch:template
input:
url: ./skeleton
values:
serviceName: ${{ parameters.serviceName }}
owner: ${{ parameters.owner }}
- id: publish
name: Publish to GitHub
action: publish:github
input:
repoUrl: github.com?owner=acme-corp&repo=${{ parameters.serviceName }}
- id: register
name: Register in Catalog
action: catalog:register
input:
repoContentsUrl: ${{ steps.publish.output.repoContentsUrl }}
catalogInfoPath: /catalog-info.yaml
A common interview question is: "How do you prevent configuration drift across hundreds of microservices?" The IDP answer is Software Templates combined with a policy of updating the template and re-scaffolding or patching existing services. Some teams use tools like Renovate Bot or custom scripts to propagate template changes (like a base image update) to all services that were created from that template. The catalog's metadata makes it possible to find all services using a given template — something impossible with ad-hoc copy-paste.