First Steps with BackstageSchritt 7 von 10: Create a Service Template
Alle Labs

Create a Service Template

Nowadays, creating new repositories for services or applications often involves a lot of repetitive tasks, such as setting up the project structure, adding CI pipelines, configuring deployment manifests and much more. As this can be a very good driver for standardization and productivity and can reduce cognitive load for developers, Backstage provides Software Templates to automate these tasks.

Software templates in Backstage are a combination of a form definition (to collect user input), a set of actions (to perform tasks) and a template (to generate files). In this section, we will create a simple Software Template to bootstrap new repositories for our services. In our example, we will create a simple template to create a new NodeJS service repository, with a Dockerfile and a GitHub Actions CI pipeline.

For simplicity, we will use the existing repository lab-backstage-basics we forked earlier as the template repository. Therefore, open the lab-backstage-basics repository in your favorite editor and create a new directory called templates in the root of the repository. In this directory, create a new file called nodejs-template.yaml with the following content:

apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
# some metadata about the template itself
metadata:
  name: nodejs-template
  title: NodeJS Service
  description: Template to create a NodeJS based Backstage service
spec:
  owner: backstage/your-github-team
  type: service

Please replace your-github-team with your actual GitHub team name. This is the metadata of our template, where we define the name, title, description, owner and type of the template.

In the next step, we will define some parameters for our template to collect user input when creating a new repository. Add the following section to the nodejs-template.yaml file:

  parameters:
    - title: Fill in some steps
      required:
        - name
        - description
      properties:
        name:
          title: Name
          type: string
          description: Unique name of the Service
        description:
          title: Description
          type: string
          description: Description of this Service
        owner:
          title: Owner
          type: string
          description: Owner of the component
          ui:field: OwnerPicker
          ui:options:
            catalogFilter:
              kind: Group
    - title: Choose a location
      required:
        - repoUrl
      properties:
        repoUrl:
          title: Repository Location
          type: string
          ui:field: RepoUrlPicker
          ui:options:
            requestUserCredentials:
              secretsKey: USER_OAUTH_TOKEN
              additionalScopes:
                github:
                  - workflow
            allowedHosts:
              - github.com
            allowedOwners:
              - your-github-organization

This section defines two parameter groups: The first group collects some basic information about the service, such as name, description and owner. The second group collects the repository location, where the new repository should be created. Please replace your-github-organization with your actual GitHub organization name. You might notice that there are some custom UI fields used in this section, such as OwnerPicker and RepoUrlPicker. These fields provide a better user experience when filling out the form in Backstage. Additionally, the RepoUrlPicker field is configured to request user credentials for creating the repository in GitHub.

💡Tip

You can find test forms and find information about the available UI fields in your Backstage installation at http://localhost:3000/create/edit.

In the next step, we will define some actions for our template to perform tasks when creating a new repository. Add the following section to the nodejs-template.yaml file:

  steps:
    - id: fetchBase
      name: Fetch Base
      action: fetch:template
      input:
        url: ../template-base
        values:
          name: ${{ parameters.name}}
          description: ${{ parameters.description }}

    - id: publish-repo
      name: Publish Repository
      action: publish:github
      input:
        gitAuthorName: ${{ user.entity.metadata.name }}
        gitAuthorEmail: ${{ user.entity.spec.profile.email }}
        repoUrl: ${{ parameters.repoUrl }}
        description: ${{ parameters.description }}
        token: ${{ secrets.USER_OAUTH_TOKEN }}

This section defines two steps: The first step fetches a base template from a local directory and replaces some values with the user input. The second step publishes the new repository to GitHub using the provided repository URL and user credentials.

📖Example Template Manifest

Putting it all together, your nodejs-template.yaml file should look like this:

apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
# some metadata about the template itself
metadata:
  name: nodejs-template
  title: NodeJS Service
  description: Template to create a NodeJS based Backstage service
spec:
  owner: backstage/your-github-team
  type: service
  parameters:
    - title: Fill in some steps
      required:
        - name
        - description
      properties:
        name:
          title: Name
          type: string
          description: Unique name of the Service
        description:
          title: Description
          type: string
          description: Description of this Service
        owner:
          title: Owner
          type: string
          description: Owner of the component
          ui:field: OwnerPicker
          ui:options:
            catalogFilter:
              kind: Group
    - title: Choose a location
      required:
        - repoUrl
      properties:
        repoUrl:
          title: Repository Location
          type: string
          ui:field: RepoUrlPicker
          ui:options:
            requestUserCredentials:
              secretsKey: USER_OAUTH_TOKEN
              additionalScopes:
                github:
                  - workflow
            allowedHosts:
              - github.com
            allowedOwners:
              - your-github-organization
  steps:
    - id: fetchBase
      name: Fetch Base
      action: fetch:template
      input:
        url: ../template-base
        values:
          name: ${{ parameters.name}}
          description: ${{ parameters.description }}
    - id: publish-repo
      name: Publish Repository
      action: publish:github
      input:
        gitAuthorName: ${{ user.entity.metadata.name }}
        gitAuthorEmail: ${{ user.entity.spec.profile.email }}
        repoUrl: ${{ parameters.repoUrl }}
        description: ${{ parameters.description }}
        token: ${{ secrets.USER_OAUTH_TOKEN }}
:::

Now, we'll have to modify the files in the `template-base` directory to use the values provided by the user. Therefore, we'll change hardcoded values in the files to use template variables instead. The files you need to modify are:

* `Dockerfile`
* `.github/workflows/build.yaml`
* `src/main.js`
* `catalog-info.yaml`
* `README.md`

For example, in the `README.md` file, you would change the content to:

```markdown
# ${{ values.name }}

This is the ${{ values.name }} service.

This way, when the template is used to create a new repository, the values provided by the user will be injected into the files. Backstage uses the Nunjucks templating engine for this purpose, so you can use Nunjucks syntax in your files.

:::validate Check your template variables To verify that your template variables are correctly set up, check the following:

  1. Open each file and ensure ${{ values.name }} and ${{ values.description }} are used instead of hardcoded values
  2. Make sure the syntax is exactly ${{ values.propertyName }} with the dollar sign and double curly braces
  3. Verify that the property names match the parameter names defined in your template :::

After making these changes, commit and push the changes to the main branch of your lab-backstage-basics repository.

Finally, we need to register the template in the Backstage Catalog, so it can be used in the Backstage application. Therefore, open the app-config.yaml file in your backstage project and add the following catalog location:

catalog:
  locations:
    - type: url
      target: https://github.com/your-github-organization/lab-backstage-basics/blob/main/template/nodejs-template.yaml
      rules:
        - allow: [Template]

This configuration tells Backstage to fetch the template from the specified URL and add it to the Catalog. Please replace your-github-organization with your current GitHub organization name.

After making this change, restart your Backstage application again, then navigate to the "Create" page in the Backstage application. You should see the "NodeJS Service" template listed there. You can now use this template to create new repositories for your NodeJS services.

When you fill out the form and submit it, Backstage will create a new repository in your GitHub organization using the provided information and the template we created. After some time, you should see the new repository appearing in the Backstage Catalog.

:::congratulations You have successfully created and used a Software Template in Backstage! :::