Platform Engineering in 2026: Building an Internal Developer Platform That Developers Actually Use
on Platform engineering, Devops, Internal developer platform, Backstage, Developer experience
Platform Engineering in 2026: Building an Internal Developer Platform That Developers Actually Use
The dirty secret of platform engineering is this: most Internal Developer Platforms (IDPs) fail not because of bad technology, but because developers don’t use them. The platform team builds a beautiful self-service portal, and then watches as engineers keep filing Jira tickets and pinging DevOps on Slack.
This post is about how to build platforms that earn adoption — covering the technical architecture, the product mindset, and the organizational dynamics that separate successful IDPs from expensive shelf-ware.
Photo by Austin Distel on Unsplash
What an IDP Actually Is
An Internal Developer Platform is the sum of tools, services, and processes that the platform team provides to application developers. The goal: let developers focus on writing business logic rather than managing infrastructure.
The key components of a mature IDP:
┌─────────────────────────────────────────────────────────┐
│ Developer Portal (Backstage) │
│ Service catalog | Docs | Templates | Metrics | Costs │
├──────────────┬──────────────┬──────────────────────────-┤
│ Self-Service Infrastructure │ Deployment Platform │
│ (Crossplane / Terraform) │ (ArgoCD / Flux) │
├──────────────┴──────────────┴──────────────────────────-┤
│ Kubernetes Control Plane │
│ (EKS / GKE / AKS / On-Prem) │
└─────────────────────────────────────────────────────────┘
The portal is the face of the platform. The control plane is the brain. Infrastructure-as-code is the muscle. All three need to work together seamlessly.
The Golden Path: Your Most Important Product
The most valuable thing a platform team builds is the golden path — the opinionated, paved road from “I have an idea” to “it’s running in production.” It’s not the only way to deploy, but it’s the way that works without needing to understand everything.
Anatomy of a Golden Path
1. Project scaffolding → service template with sensible defaults
2. Local development → consistent environment (Tilt, devcontainer)
3. CI pipeline → test, build, scan, push (pre-configured)
4. CD pipeline → progressive delivery, rollback built in
5. Observability → metrics, logs, traces out of the box
6. On-call → PagerDuty/OpsGenie rotation automated
7. Runbook → templated incident response docs
Each step in the golden path should be:
- Opinionated but escapable — the default should be good; diverging should be possible but intentional
- Self-service — no ticket to a human should be required
- Observable — developers should see what’s happening at every step
Service Templates with Backstage
Backstage’s Software Templates are the best way to encode your golden path:
# templates/microservice/template.yaml
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: python-microservice
title: Python Microservice
description: FastAPI service with observability, CI/CD, and Kubernetes deployment pre-configured
tags:
- python
- fastapi
- recommended
spec:
owner: platform-team
type: service
parameters:
- title: Service Details
required: [name, owner, description]
properties:
name:
title: Service Name
type: string
pattern: '^[a-z][a-z0-9-]{2,28}[a-z0-9]$'
description: Lowercase, hyphens only, 4-30 chars
owner:
title: Owner Team
type: string
ui:field: OwnerPicker
ui:options:
catalogFilter:
kind: Group
description:
title: Description
type: string
environment:
title: Initial Environment
type: string
enum: [dev, staging, production]
default: dev
steps:
- id: fetch-template
name: Fetch Service Template
action: fetch:template
input:
url: ./skeleton
values:
name: $
owner: $
- id: create-repo
name: Create GitHub Repository
action: publish:github
input:
repoUrl: github.com?repo=$&owner=myorg
defaultBranch: main
- id: create-argocd-app
name: Register in ArgoCD
action: argocd:create-resources
input:
appName: $
namespace: $
repoUrl: $
- id: register-catalog
name: Register in Catalog
action: catalog:register
input:
repoContentsUrl: $
catalogInfoPath: '/catalog-info.yaml'
output:
links:
- title: Repository
url: $
- title: Open in Catalog
url: $
When a developer runs this template, they get a GitHub repo, an ArgoCD application, a namespace in Kubernetes, and a Catalog entry — all in under two minutes.
Self-Service Infrastructure with Crossplane
The biggest bottleneck in most organizations: developers need a database, cache, or queue, and they have to wait for the infrastructure team.
Crossplane solves this by letting developers request cloud resources through Kubernetes manifests:
# Developer creates this file, commits it, ArgoCD syncs it
apiVersion: database.platform.myorg.io/v1alpha1
kind: PostgreSQLInstance
metadata:
name: orders-db
namespace: orders-service
spec:
parameters:
storageGB: 20
tier: standard # platform team defines what "standard" means
region: ap-northeast-2
backupEnabled: true
compositionSelector:
matchLabels:
provider: aws
environment: production
writeConnectionSecretToRef:
name: orders-db-secret # automatically injected into the namespace
The platform team defines what tier: standard maps to (RDS instance class, multi-AZ, etc.). The developer doesn’t need to know AWS internals — they just describe what they need.
Composition example (platform team writes this once)
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: postgresql-aws-production
labels:
provider: aws
environment: production
spec:
compositeTypeRef:
apiVersion: database.platform.myorg.io/v1alpha1
kind: PostgreSQLInstance
resources:
- name: rds-instance
base:
apiVersion: rds.aws.upbound.io/v1beta1
kind: Instance
spec:
forProvider:
region: us-east-1
instanceClass: db.t3.medium
engine: postgres
engineVersion: "16"
multiAz: true
storageEncrypted: true
deletionProtection: true
patches:
- fromFieldPath: spec.parameters.storageGB
toFieldPath: spec.forProvider.allocatedStorage
- fromFieldPath: spec.parameters.region
toFieldPath: spec.forProvider.region
Metrics That Matter
Most platform teams measure the wrong things. They track uptime and deployment count, but not developer experience. The DORA metrics are a start, but you need more:
DORA + DX Metrics Dashboard
# Metrics your platform team should be reporting weekly
METRICS = {
# DORA
"deployment_frequency": "deploys per team per day",
"lead_time_for_changes": "commit to production in minutes",
"change_failure_rate": "% of deploys causing incidents",
"time_to_restore": "incident MTTR in minutes",
# Platform-specific
"golden_path_adoption": "% of services using recommended templates",
"self_service_rate": "% of infra requests fulfilled without human ticket",
"portal_daily_active_users": "unique devs using portal per day",
"template_time_to_production": "minutes from template run to first deploy",
"developer_satisfaction_score": "quarterly survey, 0-10",
}
Developer satisfaction score is the most important metric and the one most platform teams ignore. Run a quarterly survey with two questions:
- On a scale of 0-10, how satisfied are you with the developer platform?
- What’s the one thing that would most improve your experience?
This qualitative signal will tell you what to build next more reliably than any quantitative metric.
The Culture Side: Why IDPs Fail
Technical quality rarely explains why an IDP fails. The failure modes are almost always cultural:
Failure Mode 1: Platform as a Gatekeeper
When the platform team treats the platform as a control mechanism (“you must use our approved tools”), developers route around it. The platform becomes a bottleneck instead of an accelerator.
Fix: Treat your internal developers as customers. Their velocity is your metric. Make the platform better than the alternative, not mandatory.
Failure Mode 2: Not Eating Your Own Dog Food
Platform teams that don’t run services themselves don’t feel the pain they’re creating. The abstractions leak, the error messages are cryptic, and the documentation is always out of date.
Fix: Require platform team members to maintain at least one production service using only the platform’s self-service tools.
Failure Mode 3: Big Bang Releases
Building the entire platform in secret and then revealing it is how you get a product that doesn’t match developer needs.
Fix: Ship one golden path end-to-end first. Get five teams using it. Learn from them. Then expand.
Photo by Jason Goodman on Unsplash
The Tech Stack That’s Working in 2026
| Layer | Tool | Why |
|---|---|---|
| Portal | Backstage | Ecosystem, plugins, active development |
| GitOps | ArgoCD | Mature, great UI, ApplicationSets |
| Infra provisioning | Crossplane | k8s-native, composable |
| Secret management | External Secrets Operator | Works with Vault, AWS SM, GCP SM |
| Progressive delivery | Argo Rollouts | Canary + blue/green, Prometheus metrics |
| Service mesh | Cilium + Gateway API | eBPF-based, replacing Istio at many orgs |
| Observability | OpenTelemetry → Grafana stack | Vendor-neutral, operator-friendly |
The Minimal Viable IDP
Don’t try to build all of this at once. Start with:
- Backstage with one template (your main service type)
- ArgoCD for GitOps (all deploys through Git)
- One observability stack (Grafana + Loki + Tempo)
That three-layer stack will eliminate most of the friction that your developers experience day-to-day. Build on top of it as adoption grows.
Measuring ROI
When the CFO asks why you’re spending engineering resources on internal tooling:
Before IDP:
- New service time-to-production: 2 weeks (infra tickets + manual setup)
- Developer hours per new service: ~40h
- Monthly new services: 8
- Monthly cost: 320 developer-hours
After IDP:
- New service time-to-production: 2 hours
- Developer hours per new service: ~4h
- Monthly new services: 8
- Monthly cost: 32 developer-hours
Savings: 288 developer-hours/month
At $150/hr fully-loaded: $43,200/month saved
The platform team’s ongoing cost needs to be lower than this. It usually is by a factor of 5–10x at scale.
What Good Looks Like
The sign of a successful platform team is when a new engineer joins, runs one command or clicks through a self-service workflow, and has a production-capable service running before lunch. No tickets. No waiting. No “let me ask someone how we do this here.”
That’s the goal. Start with the golden path, build trust, and expand from there.
이 글이 도움이 되셨다면 공감 및 광고 클릭을 부탁드립니다 :)
