Backstage Concepts

Red Hat Developer Hub, and internal developer portals in general, can be thought of as a modular system where you aggregate and display data related to the software within an organization.

The core features of Red Hat Developer Hub are the:

  • Software Catalog and Entities

  • Software Templates

  • Plugins

  • TechDocs

  • Role-Based Access Control (RBAC)

Each of these are discussed in detail below, or in a subsequent section of this module.

Software Catalog and Entities

The Software Catalog is a centralized asset tracker for all of the software in an organization. It stores and tracks Entities:

  • Components: Units of software, e.g. microservices, websites, libraries.

  • Resources: Databases, S3 buckets, brokers.

  • APIs: Represent interfaces such as REST, gRPC, and GraphQL APIs.

  • Systems: Collections of Components that make up an application or platform.

  • Domains: A higher-level grouping of Systems and Entities.

  • User: Individual users that are part of an organization.

  • Group: Groups of Users.

Custom Entity types can be defined and added to the Software Catalog using plugins. We’ll talk more about on plugins in subsequent sections.

Entities are typically imported and synchronized in one of three ways:

  1. Using plugins that automatically find and import them.

  2. Manually registering entities via the UI by providing a link to a repository containing them.

  3. Declaring them in the Backstage configuration.

In all cases, the Entities will be synchronized on a regular schedule to ensure the information in the Software Catalog remains up to date. You’ll utilize all three methods throughout this workshop.

If Entity information is stored in a Git repository, the convention is to place them in a catalog-info.yaml. This file will look similar to the following example, albeit with changes relevant to the entity being described:

apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: my-amazing-microservice
  description: A microservice written to do amazing things

  # Annotations are typically used to provide extra context to plugins, e.g TechDocs
  annotations:
    # Tells the TechDocs plugin where to find documentation sources. In this case
    # "dir:." means in the root of the repo containing this catalog-info.yaml
    backstage.io/techdocs-ref: dir:.

  # Arbitrary list of string that can be used to filter Entities in the Software Catalog
  tags:
    - docs

spec:
  type: Documentation
  lifecycle: development

  # Reference to the User or Group Entity that is responsible this Component
  owner: "pe1"

Users and Groups can be specified as owners of other Entities. If this seems abstract, don’t worry, you’ll see it in definitive terms shortly. A well curated Software Catalog enables developers to find API documentation, teams that are responsible for the Components powering those APIs, and even. view a rich dependency graph showing how various services interact with one another.

Plugins

Backstage - and by extension Red Hat Developer Hub - supports the concept of plugins. Utilizing plugins is a critical part of enabling the desired functionality for an IDP based on Backstage. For example, plugins exist to integrate with and show data from Quay or GitHub directly in Backstage. Instead of including functionality like this directly in the core Backstage project, the plugins enable platform engineering teams to customize their Backstage deployment to include only the specific functionality they need.

Why a Plugin Architecture?

Modularity and Extensibility

You can add or modify features without altering the core Backstage application. This modular approach makes it easier to extend functionality as needs evolve. Additionally, you can deploy the updates or new features independently of the main Backstage codebase, reducing the risks and efforts associated with maintaining and updating the platform.

Customization

You can tailor Backstage to fit specific workflows and use cases, enhancing the overall user experience.

Faster Iteration

You can create and test new features more rapidly as plugins, encouraging experimentation and enabling you to quickly iterate based on feedback.

Improved Collaboration

You can share plugins across teams or even externally. This sharing can foster collaboration and reduce duplication of effort, as well as help establish best practices across an organization.

Scalability

As organizations grow, their needs become complex. Plugins enable Backstage to scale alongside such complex needs, accommodating an increasing number of users and services.

Ecosystem Growth

Fostering the development of plugins can create a dynamic ecosystem around Backstage. This community can contribute to plugins that cater to different needs, thereby enhancing the platform.

Security and Compliance

You can develop plugins with specific security and compliance requirements in mind, ensuring that Backstage installations meet the necessary standards without compromising the core application.

Plugins with Upstream Backstage

Currently, running an instance of upstream Backstage and adding plugins requires a platform engineer to:

  1. Create a Backstage project using Node.js and npm.

  2. Manage new releases and updates via Backstage CLI.

  3. Install plugin(s) from npm.

  4. Edit the Backstage React and Node.js source code to load plugins, and add customizations.

  5. Test their changes.

  6. Build a container image and deploy it.

This is a tedious and time consuming process that requires JavaScript expertise and an end-to-end SDLC for releasing your new version of Backstage

Dynamic Plugins in Red Hat Developer Hub

The ability to load plugins dynamically is a value added feature included in Red Hat Developer Hub that’s currently unavailable in upstream Backstage - you can read more about it in the Red Hat Developer Hub documentation.

The dynamic plugin support in Red Hat Developer Hub means that new plugins can be installed without the need to edit code and rebuild the Red Hat Developer Hub container image. For example, installing the GitLab plugin with upstream Backstage requires adding a new dependency and editing your Backstage installation’s source code. Then you need to rebuild and test to ensure the plugin and Backstage versions are compatible. With Red Hat Developer Hub you can simply toggle plugins on or off, and they’re tested and guaranteed to be compatible with your version of Red Hat Developer Hub.

Given the vast ecosystem of Backstage plugins, the Red Hat Developer Hub team needs to be selective about which specific plugins to package and support.

Officially supported plugins and technology preview plugins (available but without support SLAs) can be seen found the plugins documentation.

You’ll see dynamic plugins in action shortly.

Understanding the Red Hat Developer Hub Configuration

Upstream Backstage uses an app-config.yaml file to define configuration values. Red Hat Developer Hub is no different.

A simple Backstage configuration file looks similar to the following example. Top-level keys generally corresponds to a feature or plugin. The values provided for a given key specify the configuration for that plugin or Backstage feature.

# Define authentication configuration (the "guest" example is for testing only)
auth:
  providers:
    guest:
      dangerouslyAllowOutsideDevelopment: true

# Static configuration for the Software Catalog. Can be used to import
# entities on startup, and restrict the entity types that can be imported.
catalog:
  rules:
    - allow: [Component, System, API, Resource, Location, Template]
  locations:
    - type: file
      target: https://github.com/org-name/repo-name/entities.yaml

# A configuration for the TechDocs plugin. This example instructs the plugin to
# build documentation at runtime, instead of pulling prebuilt HTML from S3
techdocs:
  builder: 'local'
  publisher:
    type: 'local'
  generator:
    runIn: local

You’ll be using the Red Hat Developer Hub operator to install and manage a Backstage instance - this means your app-config.yaml will be stored in a ConfigMap on OpenShift.

Software Templates

Software templates in Red Hat Developer Hub enable your team(s) to create Entities, such as new Components, and - through the use of "actions" provided by plugins - create resources in other systems such as your GitLab, GitHub, and OpenShift GitOps instances. Templates themselves are represented as Entities in the Software Catalog, meaning you can import them similar to any other Entity!

Platform Engineers will often be the authors of Templates, and use them to create "golden paths" that follow best-practices and use approved processes and tooling. Development teams will be the consumers of Templates to create new software and automate their tasks. Using Templates reduces cognitive load on the development teams by allowing them to focus on development tasks, while platform concerns are addressed by the template.

Templates are defined using YAML, but are rendered as a rich form in the Red Hat Developer Hub UI when used by development teams.

Software Template Structure

At a basic level, the Template Entity is similar to the Component Entity you encountered in the catalog-info.yaml in the prior module; resembling a Kubernetes Custom Resource.

apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
  name: quarkus-web-template
  title: Quarkus Service
  description: Creates Quarkus microservice. Uses Tekton and Argo CD for CI/CD
  tags:
    - recommended
    - java
    - quarkus
    - maven
spec:
  owner: tssc
  type: service
  # other fields removed for brevity

Where the Template Entity differs is that it contains additional fields in its spec. Let’s examine each in more detail:

  • spec.parameters (Parameters)

  • spec.steps (Steps)

  • spec.output (Output)

Parameters

The spec.parameters field is used by platform engineers to enable developers to pass values (parameters) to the Template. Typically this will be parameters such as the name of the Component, a Java package name, repository name, etc.

Here’s an example of the parameters:

spec:
  parameters:
    # Parameters can be spread across multiple forms/pages, each
    # with unique titles and set of applicable parameters
    - title: Provide Information for Application
      required:
        - component_id
        - java_package_name
      properties:
        component_id:
          title: Name
          type: string
          description: Unique name of the component
          default: my-quarkus-app
          ui:field: EntityNamePicker
          ui:autofocus: true
          maxLength: 18
        group_id:
          title: Group Id
          type: string
          default: com.redhat.rhdh
          description: Maven Group Id

You might have recognized this as a JSON Schema structure. By using JSON Schema you can define the parameters that are supported by the template, and, more importantly, enforce validation on those parameters. The rendering of the form in the Red Hat Developer Hub UI is managed by the react-jsonschema-form library.

react-jsonschema-form is a set of React components for building web forms from JSON Schema. It is core to Backstage’s scaffolder plugin’s frontend functionality, i.e the Software Template form rendering. These React components are responsible for rendering the form in which developers and end users fill out data needed to use the Software Template.

The properties that have a ui prefix might have piqued your interest. These are special properties that provide instructions to the form, for example, to enable autocomplete or autofocus certain form fields when it is displayed in the Red Hat Developer Hub UI.

Steps

Once a developer has entered and confirmed their parameters, the Template is executed by the scaffolder - a service within the Red Hat Developer Hub backend.

The scaffolder executes the actions defined in spec.steps, for example, to publish code to a Git repository and register it in the Software Catalog:

spec:
  steps:
  - id: publish
    name: Publish
    # Use the publish action provided by the GitLab plugin
    action: publish:gitlab
    input:
      # Construct a URL to the repository using the provided hostname, logged in
      # username, and provided component_id
      repoUrl: "${{ parameters.repo.host }}?owner=${{ user.entity.metadata.name }}&repo=${{parameters.component_id}}"
      repoVisibility: public
      defaultBranch: main
      sourcePath: ./${{ user.entity.metadata.name }}-${{parameters.component_id}}
  - id: register
    name: Register
    # Register a new component using the built-in register action
    action: catalog:register
    input:
      repoContentsUrl: ${{ steps.publish.output.repoContentsUrl }}
      catalogInfoPath: "/catalog-info.yaml"

Notice how the parameters are referenced and used in the steps? Another point of note is that a user variable is available to access data related to the user that’s using the Template, and subsequent steps can access output from prior steps.

The output values are documented on a per plugin basis. You can find the values for the specific version of your installed plugins by accessing the /create/actions endpoint on your Red Hat Developer Hub instance.

Output

The spec.output can use of the outputs from the steps to do display useful information such as:

  • Links to newly created Components

  • Source code repository links

  • Links to Git Merge Requests that are needed etc

  • Markdown text blobs

  output:
    links:
      - title: Source Code Repository
        url: {{ '${{ steps.publish.output.remoteUrl }}' }}
      - title: Open Component in catalog
        icon: catalog
        entityRef: {{ '${{ steps.register.output.entityRef }}' }}

Conclusion

That was a barrage of information, but it will serve you well in future sections and modules. Proceed to the next section to deploy your very own instance of Red Hat Developer Hub.