Internal Developer Platforms (IDP)

An Internal Developer Platform (IDP) is a set of self-service tools, processes and services that help accelerate development velocity and reduce time to market. An IDP provides a standardized way for development teams to configure and deploy applications and application infrastructure. It is a self-service layer allowing developers to self-serve infrastructure requirements without having to worry about container orchestration, storage provisioning etc. IDPs support a range of infrastructure and hosting options such as public cloud, private cloud and on-premises environments. Development teams can self-serve infrastructure provisioning, application deployment or create new services thus reducing the load on platform teams. IDPs streamline infrastructure decisions and integrate with existing build and deploy pipelines while providing role-based access control to developers without the need for working through a wall of YAML files.

For example, a developer creating a new microservice would start by creating a repository in SCM. They would then raise a ticket to add the necessary collaborators to the repo and provide them with the right access. They would then raise one or more tickets to create a Kubernetes cluster, storage, a database, CI/CD pipelines, configure DNS etc. An IDP can automate this process and make it frictionless. It would also remove key person dependencies and improve developer UX.

IDPs provide key features such as Infrastructure orchestration, Environment management, Deployment management, Application configuration management, and role-based access control. They promote automation, enhance integration, improve security and improve collaboration.

Backstage

Backstage is an open source tool for building Internal developer platforms. It improves the overall developer experience by delivering the core features of a developer portal, such as Software Catalogs, templates, and documentation. It helps build self-service internal tooling to enable teams to create workloads that meet compliance, regulatory and engineering requirements. It unifies tooling, services, apps, data, and docs into a single UI that allows developers to create, manage, and explore services and components. It thus brings together all aspects of a service such as its codebase, documentation, environments, infrastructure and the people who build them. It’s functionality can be extended with third-party plugins such as kubernetes {:target="_blank"}, Argo CD , github , AWS Proton , Harbor and many others .

Backstage was originally developed at Spotify as an internal developer portal. It was open sourced as a CNCF sandbox project in September 2020. It became a CNCF incubating project in March 2022. Backstage’s vision is to “to provide engineers with the best developer experience in the world.”. Backstage provides a host of features out of the box such as Service catalog, Quick start templates, documentation explorer and a robust plugin ecosystem. Let us look at some of these features.

Service Catalog

A Service Catalog enables enterprise teams to create an organized and curated collection of all software assets within an organization.The service catalog also stores a range of metadata, including documentation, ownership, programming language, source code, current version, previous updates etc.

Backstage Service Catalog

Software Templates

Backstage templates lets you define a code skeleton with organizational best practices built in. Templates ensure that software meets your requirements around security or compliance from the very beginning. Developers can use these skeletons to create new services or other workloads.

Backstage Templates

Tech Documentation

Backstage Techdocs provides developers the ability to generate documentation from markdown files. It allows developers to use the docs as code option by authoring markdown files along with code. Backstage will create and render a documentation + metadata site automatically using MkDocs.

Plugins

The plugin library allows you to extend Backstage with third-party plugins. The plugin library is a collection of plugins that can be installed and configured to extend Backstage.

Backstage technology stack

Backstage is a react based framework providing an extensible plugin architecture. It uses the Yarn package manager. It also uses the Lerna monorepo library for managing multi-package repositories. Backstage can be deployed to run on Nodejs.

Getting started with Backstage

Backstage requires an LTS version of node and Yarn installed as prerequisites. Backstage consists of the scaffolding tools and the Backstage plugin library to create a new frontend deployment of the Backstage console. We can install it using npx as below. npx runs code built with Node.js and published through the npm registry. It allows you to run and execute packages without having to install them locally or globally. npx is installed when you install node package manager.


npx @backstage/create-app

I am choosing sqlite as the backend database for this sample deployment. PostgresSQL is the preferred database for production deployments.

? Enter a name for the app [required]
>> Please enter a name for the app
? Enter a name for the app [required] pradeep-backstage-app
? Select database for the backend [required] SQLite

Creating the app...

 Checking if the directory is available:
  checking      pradeep-backstage-app ✔

 Creating a temporary app directory:
  creating      temporary directory ✔

 Preparing files:
  copying       .dockerignore ✔
  templating    .eslintrc.js.hbs ✔
  templating    .gitignore.hbs ✔
  copying       .prettierignore ✔
  copying       README.md ✔
  copying       app-config.production.yaml ✔
  templating    app-config.yaml.hbs ✔
  templating    backstage.json.hbs ✔
  templating    catalog-info.yaml.hbs ✔
  copying       lerna.json ✔
  templating    package.json.hbs ✔
  copying       tsconfig.json ✔
  copying       README.md ✔
  copying       README.md ✔
  templating    .eslintrc.js.hbs ✔
  copying       Dockerfile ✔
  copying       README.md ✔
  templating    package.json.hbs ✔
  copying       index.test.ts ✔
  copying       index.ts ✔
  copying       types.ts ✔
  copying       app.ts ✔
  copying       auth.ts ✔
  copying       catalog.ts ✔
  copying       proxy.ts ✔
  copying       scaffolder.ts ✔
  templating    search.ts.hbs ✔
  copying       techdocs.ts ✔
  templating    .eslintrc.js.hbs ✔
  copying       cypress.json ✔
  templating    package.json.hbs ✔
  copying       android-chrome-192x192.png ✔
  copying       apple-touch-icon.png ✔
  copying       favicon-16x16.png ✔
  copying       favicon-32x32.png ✔
  copying       favicon.ico ✔
  copying       index.html ✔
  copying       manifest.json ✔
  copying       robots.txt ✔
  copying       safari-pinned-tab.svg ✔
  copying       .eslintrc.json ✔
  copying       app.js ✔
  copying       App.test.tsx ✔
  copying       App.tsx ✔
  copying       apis.ts ✔
  copying       index.tsx ✔
  copying       setupTests.ts ✔
  copying       LogoFull.tsx ✔
  copying       index.ts ✔
  copying       Root.tsx ✔
  copying       LogoIcon.tsx ✔
  copying       EntityPage.tsx ✔
  copying       SearchPage.tsx ✔

 Moving to final location:
  moving        pradeep-backstage-app ✔

 Building the app:
  executing     yarn install ✔
  executing     yarn tsc ✔

🥇  Successfully created pradeep-backstage-app


 All set! Now you might want to:
  Run the app: cd pradeep-backstage-app && yarn dev
  Set up the software catalog: https://backstage.io/docs/features/software-catalog/configuration
  Add authentication: https://backstage.io/docs/auth/

This generates the code for the Backstage app. The generated code can be run using the yarn dev script as below.

$ yarn dev                                                                                                                                                               ✔
yarn run v1.22.18
$ concurrently "yarn start" "yarn start-backend"
$ yarn workspace app start
$ yarn workspace backend start
$ backstage-cli package start
$ backstage-cli package start
......
......
......

This starts as a development server running on port 3000 running your very own vanilla Internal Developer Platform on Backstage.

Backstage

Backstage repository structure

We now have an instance of backstage up and running, Let us understand how backstage code is structured. Backstage is a monorepo. A monorepo is a code organization and an architectural concept where a single repository contains multiple distinct projects with well-defined relationships. A monorepo allows for a single location to store all configurations. It allows for easier dependency management. The single codebase makes it easy to reuse code and libraries between projects. However a monorepo requires a good build system to make it work. Bazel is an example such a build system. It is highly opinionated but delivers an extremely fast, hermetic, and reproducible build process. Let us further deepdive into the Backstage monorepo structure.

Backstage Monorepo structure

The source for the Backstage UI is found in the packages/app folder. The source for the plugins can be found in the plugins folder. The app folder and each of the plugin folders are independent npm packages complete with their own package.json. Both Lerna and Yarn work together to create this seamless monorepo structure. The workspace features of Yarn allow a single monorepo to contain the source for multiple npm packages. The yarn workspaces comprised of these folders is defined in project.json as below

"workspaces": {
    "packages": [
      "packages/*",
      "plugins/*"
    ]
  },

The above configuration tells yarn that any child folders in the packages and plugin folders are separate workspaces containing npm packages. This makes it easy for these npm packages to reference each other. For example a package can reference a plugin as below

export { BrowseContainersPlugin } from './plugin';

The package.json file as in any node.js project system is the manifest for the project. It stores the names and versions of all installed packages. It is the central repository for tool configuration for the codebase. It also provides npm scripts which can be shared by everyone using that codebase. The Backstage package.json file provides a bunch of scripts that can be used against the codebase. It provides both lerna and yarn scripts. Lerna is used for scripts that need to be run against multiple workspaces.

"scripts": {
    "dev": "concurrently \"yarn start\" \"yarn start-backend\"",
    "start": "yarn workspace app start",
    "start-backend": "yarn workspace backend start",
    "build": "backstage-cli repo build --all",
    "build-image": "yarn workspace backend build-image",
    "tsc": "tsc",
    "tsc:full": "tsc --skipLibCheck false --incremental false",
    "clean": "backstage-cli clean && lerna run clean",
    "diff": "lerna run diff --",
    "test": "backstage-cli test",
    "test:all": "lerna run test -- --coverage",
    "lint": "backstage-cli repo lint --since origin/master",
    "lint:all": "backstage-cli repo lint",
    "prettier:check": "prettier --check .",
    "create-plugin": "backstage-cli create-plugin --scope internal",
    "remove-plugin": "backstage-cli remove-plugin"
  },

I can lint the codebase using the lint script in the package.json using npm as below

$ npm run lint:all

> root@1.0.0 lint:all
> backstage-cli repo lint

Checked  10 files in packages/backend 1.07s
Checked  12 files in plugins/pradeep-plugin 0.39s
Checked  12 files in packages/app 1.57s

Creating custom plugins

Backstage has a rich plugin ecosystem. Some of the plugins available can be found here . If these plugins do not tick all the boxes we can create our own custom plugin. We can use the backstage cli to create plugins. To get started we can install the backstage cli using npm npm i @backstage/cli -g. We can now use the backstage cli to create a new plugin as below

$ backstage-cli create-plugin
? Enter an ID for the plugin [required] helloworld

Creating the plugin...

 Checking if the plugin ID is available:
  checking      /home/pradeepl/source/repos/mybackstage/pradeep-backstage-app/plugins/helloworld ✔

 Creating a temporary plugin directory:

 Preparing files:
  copying       .eslintrc.js ✔
  templating    README.md.hbs ✔
  templating    package.json.hbs ✔
  templating    index.tsx.hbs ✔
  templating    index.ts.hbs ✔
  templating    plugin.test.ts.hbs ✔
  templating    plugin.ts.hbs ✔
  templating    routes.ts.hbs ✔
  copying       setupTests.ts ✔
  templating    ExampleComponent.tsx.hbs ✔
  templating    ExampleComponent.test.tsx.hbs ✔
  copying       index.ts ✔
  templating    ExampleFetchComponent.tsx.hbs ✔
  copying       index.ts ✔
  templating    ExampleFetchComponent.test.tsx.hbs ✔

 Moving to final location:
  moving        helloworld ✔

 Building the plugin:
  executing     yarn install ✔
  executing     yarn lint --fix ✔
  executing     yarn tsc ✔
  executing     yarn build ✔

 Adding plugin as dependency in app:
  processing    packages/app/package.json ✔

 Import plugin in app:
  processing    /home/pradeepl/source/repos/mybackstage/pradeep-backstage-app/packages/app/src/App.tsx ✔

🥇  Successfully created plugin-helloworld

The create-plugin command creates a new plugin under the plugins folder. It also imports the plugin into the backstage app and creates the necessary routes. The main plugin code is in the ExampleComponent.tsx file in the /plugins/helloworld/src/components/ExampleComponent folder. You can now view your plugin by running ```yarn start`` in the route directory and navigating to http://localhost:3000/helloworld. We can customize the generated react code to add the necessary functionality.

Using existing plugins

Backstage has a rich plugin ecosystem. We can use an existing plugin in our backstage app. Let us add the Tech Radar plugin . You can read more about the Tech Radar plugin here . There are two ways to add a plugin to our backstage app.

  • Simple - You can install the plugin using the command yarn add --cwd packages/app @backstage/plugin-tech-radar. The plugin is now available in the /tech-radar path of your backstage app.
  • Advanced - In the advanced installation you can use the react component directly by inserting it into a page. This provides more customization options.

I am adding the plugin using the simple method.

Backstage Tech Radar

Packaging the Backstage app

We have now created a starter Internal Developer Platform using Backstage. We can package the app as a docker container and deploy it to a kubernetes cluster. The steps to deploy a backstage app to a kubernetes cluster is here

Conclusion

Internal Developer platforms play a key role in developer UX and improve development velocity. They make teams independent and provide a paved path self serve infrastrcuture, environments etc by applying organizational best practices. Backstage provides the necessary framework to create an IDP that suits an organization. Backstage has a rich ecosystem of plugins that allow the IDP to extended and enhanced. Backstage powers the IDP’s of large organizations like spotify, american airlines and others. It is a key open source project with great ecosystem of contributors. So what are you waiting for ?