A Grain of Salt

Internal Developer Portals: The Unified Interface to Your Platform

· Teddy Aryono

In previous posts, we explored platform architecture and the importance of building abstractions that accelerate rather than limit. Now we turn to a critical component of the platform stack: the internal developer portal. This is the interface layer that brings coherence to your platform, providing developers with a single front door to all platform capabilities.

Understanding internal developer portals is essential for platform teams because they represent the primary way developers experience your platform. A well-designed portal can dramatically reduce cognitive load and time-to-productivity. A poorly designed one becomes yet another tool to learn, defeating the purpose of platform engineering.

The Problem Portals Solve

Modern software development requires interacting with dozens of systems: CI/CD pipelines, monitoring dashboards, logging platforms, cloud consoles, documentation wikis, on-call schedules, deployment tools, service catalogs, and more. Each system has its own interface, authentication, and conventions. Developers spend significant time just navigating this landscape.

Cognitive Overload - Switching between tools is mentally exhausting. Where’s the deployment dashboard? Which wiki has the runbook? Where do I find service metrics? Each context switch breaks flow and reduces productivity.

Discoverability - Basic questions require tribal knowledge or Slack archaeology. “How do I deploy a service?” “Where’s the documentation for that API?” “Who owns this service?” New team members face a particularly steep learning curve.

Inconsistency - Every team documents differently, structures their repositories differently, names things differently. Without standards, finding information becomes a scavenger hunt.

Onboarding Friction - New developers must learn not just the codebase but the entire tooling landscape. Where everything is, how to navigate between systems, who to ask for help. This dramatically increases time-to-first-contribution.

Internal developer portals address these problems by providing a unified interface that brings together information and actions from across the platform into one coherent experience.

What Is an Internal Developer Portal?

An internal developer portal is the unified front door to your platform. It’s a web application that serves as the central hub for developers to discover services, access documentation, trigger deployments, view metrics, and generally interact with platform capabilities.

The portal doesn’t replace other tools - it unifies them. Source control, CI/CD, monitoring, and deployment tools continue to exist and function independently. The portal integrates with these tools, presenting a coherent view organized around your services rather than around individual tools.

Think of it as mission control for your software. Instead of checking five different dashboards to understand the state of a service, you look at one page that aggregates information from all relevant systems.

Core Capabilities of Developer Portals

Successful portals typically provide:

Service Catalog - A centralized registry of all software in your organization. Every service, library, API, and resource is cataloged with metadata about ownership, relationships, lifecycle stage, and links to relevant resources.

Documentation Hub - Centralized, searchable documentation that lives alongside code. Technical docs, runbooks, architecture decision records, API specifications - all discoverable from one place.

Self-Service Actions - Developers can accomplish common tasks without tickets or manual intervention. Create a new service, provision a database, trigger a deployment, create an environment.

Service Ownership - Clear mapping of who owns what. Team structure, on-call rotations, escalation paths. No more “who do I ask about this service?”

Unified Dashboards - Each service has a page aggregating information from multiple systems: source code, build status, deployment state, running pods, metrics, logs, recent incidents.

Search and Discovery - Find services by name, technology, team, or purpose. Discover APIs, understand dependencies, explore the architecture.

Templates and Scaffolding - Create new projects with organizational best practices baked in. No more copying old repos and inheriting their quirks.

Backstage: The Reference Implementation

Spotify’s Backstage, now a CNCF project, has emerged as the leading open-source internal developer portal. Understanding Backstage provides insight into portal architecture and best practices.

Architecture Overview

Backstage is built as a plugin platform with several core concepts:

The Software Catalog is Backstage’s heart - a centralized registry where everything in your software ecosystem is represented as an entity. The catalog provides a unified view of your entire software landscape.

The Frontend is a React application providing the user interface. It’s extensible through frontend plugins that add pages, components, and functionality.

The Backend consists of Node.js services that handle catalog management, execute templates, provide search, and proxy requests to external systems through backend plugins.

Plugins are the extensibility mechanism. Core plugins integrate with common tools (GitHub, Kubernetes, ArgoCD, PagerDuty), while custom plugins add organization-specific capabilities.

The Software Catalog: Core Concept

The catalog is declarative. Services describe themselves using YAML files committed to their repositories:

 1apiVersion: backstage.io/v1alpha1
 2kind: Component
 3metadata:
 4  name: payment-api
 5  description: Payment processing API
 6  annotations:
 7    github.com/project-slug: myorg/payment-api
 8    pagerduty.com/integration-key: abc123
 9    grafana/dashboard-selector: payment-api
10spec:
11  type: service
12  lifecycle: production
13  owner: payments-team
14  system: payment-system
15  providesApis:
16    - payment-api-v1
17  consumesApis:
18    - billing-api-v1
19  dependsOn:
20    - resource:payment-database

This catalog-info.yaml file lives in the service’s repository. It declares:

Backstage discovers these files automatically by watching repositories or through integrations. The catalog builds a comprehensive map of your software ecosystem without manual curation.

Entity Types

The catalog supports multiple entity types that together model your entire software landscape:

Components are individual pieces of software - services, libraries, websites, data pipelines. Each component has clear ownership and lifecycle stage.

APIs represent contracts between services. Backstage can ingest OpenAPI, GraphQL, or other specs and render them beautifully. APIs are first-class entities that can be versioned, owned, and tracked independently.

Resources are infrastructure that components depend on - databases, S3 buckets, message queues, cache clusters. Resources are linked to their consumers, providing visibility into dependencies.

Systems are collections of components that form a product or capability. “Payment System” might include payment-api, payment-worker, payment-database, and payment-analytics. Systems provide organizational structure above individual components.

Domains are higher-level groupings representing business capabilities. “E-commerce Domain” might include payment, shopping-cart, and inventory systems.

Groups and Users represent your organization structure. Teams own components and systems. Users belong to teams. The org chart is part of the catalog.

This multi-level structure - components within systems within domains, owned by teams within the organization - provides flexible ways to organize and discover software.

Software Templates: Self-Service Scaffolding

Templates enable developers to create new projects with organizational best practices built in. Instead of copying an old service and modifying it (inheriting its quirks and outdated patterns), developers use templates that generate fresh, correct implementations.

A template workflow typically:

  1. Prompts for inputs (service name, team, configuration options)
  2. Generates code from a skeleton with variables filled in
  3. Creates a Git repository
  4. Sets up CI/CD pipelines
  5. Provisions initial infrastructure
  6. Registers the service in the catalog
  7. Creates documentation structure

Templates are defined declaratively:

 1apiVersion: scaffolder.backstage.io/v1beta3
 2kind: Template
 3metadata:
 4  name: python-service-template
 5  title: Python Microservice
 6  description: Create a new Python microservice with FastAPI
 7spec:
 8  owner: platform-team
 9  type: service
10  
11  parameters:
12    - title: Service Details
13      required:
14        - name
15        - owner
16      properties:
17        name:
18          title: Name
19          type: string
20          description: Unique name for this service
21        owner:
22          title: Owner
23          type: string
24          ui:field: OwnerPicker
25        database:
26          title: Database
27          type: string
28          enum: [none, postgres, mysql, mongodb]
29          
30  steps:
31    - id: fetch-base
32      name: Fetch Base Template
33      action: fetch:template
34      input:
35        url: ./skeleton
36        values:
37          name: ${{ parameters.name }}
38          owner: ${{ parameters.owner }}
39    
40    - id: create-repo
41      name: Create GitHub Repository
42      action: github:repo:create
43      input:
44        repoUrl: github.com?repo=${{ parameters.name }}
45        
46    - id: provision-infrastructure
47      name: Provision Infrastructure
48      action: terraform:apply
49      input:
50        template: service-infrastructure
51        values:
52          service_name: ${{ parameters.name }}
53          database_type: ${{ parameters.database }}
54        
55    - id: register
56      name: Register in Catalog
57      action: catalog:register
58      input:
59        repoContentsUrl: ${{ steps.create-repo.output.repoContentsUrl }}
60        catalogInfoPath: /catalog-info.yaml

This template creates a complete, production-ready service. The developer answers a few questions; the platform handles everything else.

This is where the portal connects to Infrastructure as Code. Templates can execute arbitrary actions, including triggering Terraform, calling cloud APIs, or creating Kubernetes resources. The portal orchestrates complex workflows that span multiple systems.

TechDocs: Documentation as Code

Backstage includes built-in support for “docs like code.” Documentation lives in the same repository as the code it describes, written in Markdown, version-controlled, and reviewed in pull requests.

Benefits of this approach:

TechDocs uses MkDocs under the hood, providing a familiar, powerful documentation framework. Developers write Markdown; Backstage renders it beautifully with navigation, search, and consistent styling.

The Plugin Ecosystem

Backstage’s power comes from its plugin architecture. The core provides the catalog and UI framework; plugins add capabilities by integrating with external systems.

Frontend plugins add UI pages and components visible to users:

The Kubernetes plugin shows pod status, logs, events, and resource usage. Developers can debug deployment issues without leaving the portal.

The PagerDuty plugin displays on-call schedules, recent incidents, and alert status. Clear visibility into who’s on-call and current incident state.

The Cost Insights plugin shows cloud spending per service, cost trends, and optimization opportunities. Teams understand their infrastructure costs.

The CI/CD plugins (CircleCI, GitHub Actions, Jenkins) show build status, test results, and deployment pipelines.

Backend plugins integrate with external systems, providing data to the frontend:

The GitHub plugin syncs repositories, pull requests, and contributor information into the catalog.

The ArgoCD plugin provides deployment status, sync state, and application health from your GitOps controller.

The Prometheus plugin queries metrics and provides data for custom dashboards.

The Vault plugin manages secrets and provides secure access to sensitive configuration.

The Service Page: Unified View

Each service in the catalog has a dedicated page that aggregates information from multiple plugins. A typical service page might show:

Instead of visiting ten different tools, developers see everything relevant to their service in one place.

How the Portal Connects to Platform Capabilities

The portal is the interface layer, but it triggers and visualizes capabilities built on deeper platform layers.

Service Creation Flow

  1. Developer uses a template in Backstage
  2. Template generates code from skeleton
  3. Template creates Git repository via GitHub API
  4. Template triggers Infrastructure as Code (Terraform/Pulumi) to provision infrastructure
  5. GitOps controller (ArgoCD) detects new repository and deploys application
  6. Template registers service in catalog
  7. Service appears in portal with links to repo, pipelines, deployments

The portal orchestrated this entire workflow, but IaC provisioned the infrastructure and GitOps handles ongoing deployment.

Infrastructure Provisioning

When a developer needs a database through the portal, several approaches are possible:

Direct IaC Execution - Portal backend calls Terraform/Pulumi directly. Provisions the database, returns connection information. Fast but requires portal to manage IaC execution.

GitOps-Style - Portal creates a pull request in an infrastructure repository containing the database definition. Team reviews, merges. GitOps tool applies the change. Slower but maintains Git as source of truth and enables review.

Kubernetes Operator - Portal creates a Kubernetes Custom Resource representing the database. Operator watches for these resources and provisions infrastructure. Clean integration if you’re Kubernetes-centric.

The portal provides the interface; the implementation layer (IaC, operators) does the actual work.

Visualization and Status

The portal doesn’t just trigger actions - it provides visibility into what’s happening:

Deployment Status - ArgoCD plugin shows whether services are synced, healthy, degraded. Developers see deployment state without accessing ArgoCD directly.

Infrastructure Status - Terraform plugin shows workspace state, recent runs, resource counts.

Build Status - CI plugin shows whether the latest commit built successfully, test pass rates, coverage trends.

The portal becomes mission control, aggregating status from across the platform.

Beyond Backstage: Alternative Portals

While Backstage is the most prominent open-source option, alternatives exist:

Port - More opinionated, SaaS-first. Strong focus on infrastructure visibility and self-service actions. Good for teams that want quick setup over maximum flexibility.

Cortex - Emphasis on service ownership, scorecards for production readiness, and service maturity tracking. Good for organizations focused on operational excellence.

OpsLevel - Service catalog with focus on microservices management, service maturity, and developer productivity metrics.

Rely.io - Service catalog and developer portal with emphasis on developer experience and reducing cognitive load.

Backstage offers maximum flexibility and extensibility but requires more investment to customize. SaaS options provide faster time-to-value but less customization.

What Makes a Good Developer Portal

Based on successful implementations:

Comprehensive Service Catalog - Single source of truth for what exists, who owns it, how components relate. If developers can’t find it in the catalog, they won’t use the portal.

Self-Service Actions - Developers can accomplish common tasks without tickets or manual intervention. The portal should enable action, not just information.

Unified Discovery - Everything is searchable and browsable. Developers should be able to find what they need through search, browsing, or following relationships.

Contextual Information - Each service page shows relevant information from multiple systems. Developers see everything they need in context.

Low Maintenance - The catalog should be automatically updated through integrations, not manually curated. Manual curation doesn’t scale and becomes stale.

Fast and Reliable - If the portal is slow or flaky, developers won’t use it. Performance and reliability are essential.

Extensible - You can add organization-specific tools and workflows. Every organization has unique needs.

Clear Ownership Model - The catalog makes it obvious who owns what. No more “who do I ask about this?”

The Portal’s Role in Platform Architecture

Returning to our three-layer architecture from previous posts:

Implementation Layer - Infrastructure as Code, CI/CD systems, monitoring tools, Kubernetes clusters. This is where actual work happens.

Capability Layer - Deployment, infrastructure provisioning, observability, secrets management. These capabilities are built using implementation layer tools.

Interface Layer - The developer portal sits here, providing a unified way to access capabilities.

The portal doesn’t replace other tools; it unifies them:

The value is integration and coherence. Instead of fifteen separate tools organized around different concerns (CI, deployment, monitoring, etc.), you have one interface organized around your services.

Implementation Considerations

Building a developer portal requires careful planning:

Start Small - Don’t try to integrate everything on day one. Start with the service catalog and basic integrations. Add capabilities iteratively based on feedback.

Integrate with Existing Tools - Don’t replace working tools. The portal should enhance, not replace. If developers are happy with their CI/CD tool’s interface, just link to it from the portal.

Invest in Catalog Quality - The catalog is the foundation. If it’s incomplete or stale, nothing else matters. Make catalog updates automatic through integrations.

Make Self-Service Genuinely Easy - Self-service actions should be easier than the manual process. If templates are complicated or slow, developers won’t use them.

Measure Adoption and Value - Track portal usage, template adoption, time-to-first-deployment. Measure whether the portal reduces support tickets and improves productivity.

Provide Training and Documentation - The portal itself needs documentation. Create guides, videos, and onboarding materials.

Iterate Based on Feedback - Regular user research with developers. What’s working? What’s frustrating? What’s missing?

Common Anti-Patterns

Several mistakes undermine portal effectiveness:

Information Graveyard - Catalog becomes a dumping ground for stale information. Services that no longer exist, outdated ownership, broken links. Maintain catalog quality through automation and regular cleanup.

Feature Overload - Trying to integrate every possible tool creates a cluttered, overwhelming interface. Focus on high-value integrations.

Disconnected from Reality - Portal shows information that doesn’t match actual system state. Caused by stale data or broken integrations. Invest in reliable, real-time integrations.

Ignoring Mobile/Performance - Developers increasingly work from various devices and locations. Portal should be responsive and fast.

Unclear Ownership - If developers don’t know who maintains the portal or how to get help, it becomes frustrating.

Building in Isolation - Portal team builds features without developer input, resulting in capabilities nobody uses.

Key Takeaways

For Engineering Leaders:

For Platform Engineers:

For Both:

Looking Ahead

Internal developer portals provide the interface layer of your platform, but they’re powered by foundational building blocks. In the next post, we’ll dive deep into two critical foundations: Infrastructure as Code and GitOps. These patterns enable the platform capabilities that developers access through the portal. Understanding how IaC and GitOps work, and how they integrate with the portal layer, completes the picture of how modern platforms operate.


This is the fifth post in a series exploring platform engineering in depth. Previous posts covered platform fundamentals, SRE relationships, platform architecture, and building useful abstractions.

#platform-engineering

Reply to this post by email ↪