Platform Tips #23: Building a Better Alternative To Backstage - Part II
Let's build together an alternative to Backstage focusing on ease of use, low maintenance and developer experience. This is the part II of a series of III.
Hey Folks 👋,
I'm Romaric, CEO of Qovery, and this is my 23rd Platform Tips post.
Last week, we talked about part I of this series of 3 articles on how to build a better alternative to Backstage, focusing on three pillars:
Part II: Low maintenance (it just works) ← [YOU READ THIS ONE]
Part III: Intuitive for developers (Developer Experience)
In this series of three articles, I aim to explore what these pillars truly entail, both from a product perspective and technically. The goal is to propose a concrete solution to Backstage that focuses on ease of use, low maintenance, and Developer Experience. Feel free to challenge each of those points and propose even something better 😎. Multiple smart brains are better than only one brain here 🧠.
Note 👀: those articles are a great introduction to how Torii (the concrete alternative to Backstage I am working on) is built. The code is available here but not yet usable. Expect to be able to use Torii for May 2024.
Feel free to take those concepts, adapt and apply them to any alternative to Backstage that you might build - or join and contribute to Torii ⛩️
Low Maintenance
Before proposing solutions to reduce the maintenance of our Internal Developer Portal, let's first identify what factors contribute to the high maintenance of Backstage.
The complexity of Backstage mainly arises from two key aspects:
Using React for Plugin Development: Opting to use React for Backstage development introduces an additional layer of complexity, especially for Platform Engineering teams. Members of these teams often come from IT backgrounds, with a primary focus on backend development. Their familiarity with frontend technologies, particularly React, is usually limited. This requires gaining proficiency in a new platform framework like Backstage and acquiring skills in a different programming language.
Lack of Reusability for Existing Scripts: Platform engineers often handle various scripts and configurations like Terraform, Pulumi, Helm Charts, Python, and Bash. Unfortunately, Backstage does not easily facilitate the reuse of these resources. As a result, engineers end up duplicating work they've already done, causing redundant efforts and inefficiencies.
Those requirements unnecessarily complicate the implementation process, making it more challenging than necessary for platform engineers to effectively maintain an Internal Developer Portal.
So here are my proposals to fix those issues.
No React
The idea would be to make our Backstage alternative 100% customizable for Platform Engineering teams by using YAML. It’s possible if we:
Provide enough base components.
Make them extensible by offloading the business logic backend side (instead of frontend with Backstage).
For the first point, base components for the self-service feature would be providing the ability to configure the fields. Let’s say we have a text input field, then the YAML would be:
...
fields:
- slug: name
title: Name
type: text
required: true
...
If we want to add a field validation capability to this field that would be offloaded on the backend side, we could add a validation-script property:
...
fields:
- slug: name
title: Name
type: text
required: true
validate:
command:
- python
validate-name.py
...
The validate-name.py script could look like this:
import sys
import json
if __name__ == '__main__':
# a JSON is passed from the backend as the first ARG
input_json = json.loads(sys.argv[1])
name_field_value = input_json['value']
if len(name_field_value) > 20:
print("Your name can't be higher than 20 characters")
sys.exit(1)
for ch in name_field_value:
# checking for uppercase character and flagging
if ch.isupper():
print("Your name must be in lowercase")
sys.exit(1)
The execution flow would be like this:
The user fill the “name” field with “My Cluster”
The validation script is executed
An error is returned to the user “Your name must be lowercase”
We could even:
Imagine to check that the name does not already exist via a database, API, or anything else…
Add other field capabilities with the same mechanism like:
auto-complete suggestions: return a list of suggestions based on the input value and the result of an executed script.
permissions: give access or not to the field based on the result of an executed script.
visibility logic: show the field based on the result of an executed script.
… <put your idea here>
Possibilities are limitless.
Use Your Own Scripts
Backstage prevents you using your own scripts by design. It’s a shame since most of Platform Engineering teams have already existing scripts. Let’s say, you have this Terraform manifest to provision a RDS instance:
terraform {
...
}
provider "aws" {
...
}
resource "aws_db_instance" "rds_instance" {
allocated_storage = 20
storage_type = "gp2"
engine = "mysql"
engine_version = "8.0.27"
instance_class = "db.t2.micro"
name = var.name
username = var.username
password = var.password
publicly_accessible = true
skip_final_snapshot = true
}
This is just an example to illustrate how to reuse your existing scripts - in most organizations you might want to execute this Terraform manifest from a CI/CD pipeline in a GitOps way.
With Backstage you will have to either:
Create a custom plugin for Terraform in React
In our Backstage alternative, since everything is offloaded on the backend side, we could simply execute our Terraform manifest by passing the user input values:
...
self_service:
sections:
- slug: default
name: Default
description: Default section
actions:
- slug: new-cluster
name: New Cluster
description: spin up a new cluster
icon: target
fields:
- slug: name
title: Name
type: text
required: true
post_validate:
- command:
- terraform
- init
- &&
- terraform
- apply
- -f
- new-cluster/main.tf
- -auto-approve
- -var
- name={{name}} # this is a variable that will be replaced by the value of the field 'name'
- -var
- username={{function.random()}} # function to generate a random string
- -var
- password={{function.random()}} # function to generate a random string
The execution flow looks like this:
This example is applicable not only with Terraform but any technology.
Conclusion
In this part we have seen how we could lower the maintenance effort for Platform Engineering teams by reusing their own scripts and by re-imagining the way they could configure UI components and make them extensible. In Part III (next week), we will dig into how to keep a simple and intuitive Developer Experience for developers.
Until that, feel free to share your feedback about this post. Have a great week.
—
Let's revolutionize Platform Engineering by putting developers first. Subscribe now to join me on this exciting journey!