Platform Engineering in 2026: Building an Internal Developer Platform That Teams Actually Use
on Platform engineering, Idp, Backstage, Developer experience, Devops, Kubernetes, Gitops
Platform Engineering in 2026: Building an Internal Developer Platform That Teams Actually Use
The DevOps movement told developers: “you build it, you run it.” That was transformative — and also, for many teams, a disaster. Engineers spending 40% of their time on infrastructure, compliance, security configs, and CI/CD debugging is not what “you build it, you run it” was supposed to mean.
Platform Engineering is the answer: build an Internal Developer Platform (IDP) that abstracts the complexity away, so product teams can self-service their infrastructure needs without becoming Kubernetes experts. Done right, it’s the highest-leverage investment a platform team can make. Done wrong, it becomes an under-used portal that nobody trusts.
This post is about doing it right.
Photo by Growtika on Unsplash
What Is an Internal Developer Platform?
An IDP is the sum of tools, services, and workflows that your platform team provides so product engineers can:
- Deploy applications without writing Kubernetes YAML
- Provision databases, queues, and caches without filing tickets
- Get observability (logs, metrics, traces) automatically
- Pass security and compliance checks without becoming security experts
- Understand their service’s health, dependencies, and ownership at a glance
The core concept is the Golden Path — the paved road that’s so easy and good that teams choose it voluntarily. Not a mandate; an offer they can’t refuse.
The CNCF Platform Maturity Model
The CNCF’s Platform Engineering working group defines four maturity levels:
| Level | Name | Characteristics |
|---|---|---|
| 1 | Provisional | Ad-hoc tools, no formal platform team |
| 2 | Operational | Shared tooling, some self-service |
| 3 | Scalable | Self-service portal, product thinking applied to platform |
| 4 | Optimizing | Platform as a product, SLOs, continuous improvement loop |
Most organizations in 2026 are at Level 2 trying to reach Level 3. The jump from 2 to 3 is the hardest: it requires platform teams to adopt product management practices, not just engineering practices.
The Core Components
A modern IDP in 2026 typically consists of:
┌─────────────────────────────────────────────────────────┐
│ Developer Portal (Backstage) │
│ Service Catalog | Docs | Templates | Dependency Map │
└─────────────────────────────────┬───────────────────────┘
│
┌───────────────────┼───────────────────┐
↓ ↓ ↓
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Application │ │ Infrastructure │ │ Observability │
│ Delivery │ │ Self-Service │ │ Platform │
│ │ │ │ │ │
│ • ArgoCD │ │ • Crossplane │ │ • Prometheus │
│ • Tekton/GHA │ │ • Terraform CDK │ │ • Grafana │
│ • OCI Registry │ │ • PostgreSQL │ │ • Jaeger/Tempo │
│ • Helm/Kustomize│ │ • Redis, S3 │ │ • OpenTelemetry │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│
┌─────────────────────────────────────────────────────────┐
│ Security & Policy Layer │
│ OPA/Kyverno | Vault | RBAC | Audit Logging │
└─────────────────────────────────────────────────────────┘
Setting Up Backstage: The Developer Portal
Backstage (Spotify → CNCF) has become the de facto developer portal. Here’s a production setup:
Bootstrap
npx @backstage/create-app@latest --name my-platform
cd my-platform
yarn install
Service Catalog: The Foundation
Every service in your organization should register in Backstage via a catalog-info.yaml in the repo root:
# catalog-info.yaml (lives in each service repo)
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: payment-service
description: Handles payment processing for all checkout flows
annotations:
github.com/project-slug: myorg/payment-service
backstage.io/techdocs-ref: dir:.
grafana/dashboard-selector: "payment-service"
opsgenie.com/component-selector: payment-service
tags:
- node
- payments
- pci-dss
links:
- url: https://grafana.internal/d/payment-service
title: Grafana Dashboard
icon: dashboard
- url: https://runbooks.internal/payment-service
title: Runbooks
icon: docs
spec:
type: service
lifecycle: production
owner: payments-team
system: checkout
dependsOn:
- component:order-service
- resource:payments-postgres
- resource:stripe-api
providesApis:
- payment-api
Software Templates: Self-Service Service Creation
This is where the magic happens. Teams create new services via Backstage without touching infrastructure:
# templates/nodejs-service/template.yaml
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: nodejs-microservice
title: Node.js Microservice
description: Creates a production-ready Node.js microservice with CI/CD, observability, and database
tags:
- node
- microservice
- recommended
spec:
owner: platform-team
type: service
parameters:
- title: Service Details
required: [name, description, owner]
properties:
name:
title: Service Name
type: string
pattern: '^[a-z][a-z0-9-]*[a-z0-9]$'
description: "Lowercase, hyphen-separated (e.g., user-profile-service)"
description:
title: Description
type: string
ui:widget: textarea
owner:
title: Owner Team
type: string
ui:field: OwnerPicker
ui:options:
catalogFilter:
kind: Group
- title: Infrastructure
properties:
database:
title: Database
type: string
default: none
enum: [none, postgres, mysql]
cache:
title: Cache
type: boolean
default: false
description: Provision a Redis instance
- title: Repository
required: [repoUrl]
properties:
repoUrl:
title: Repository Location
type: string
ui:field: RepoUrlPicker
ui:options:
allowedHosts: [github.com]
steps:
- id: fetch-template
name: Fetch Template
action: fetch:template
input:
url: ./skeleton
values:
name: $
description: $
owner: $
database: $
cache: $
- id: publish
name: Publish to GitHub
action: publish:github
input:
allowedHosts: [github.com]
description: $
repoUrl: $
defaultBranch: main
repoVisibility: internal
- id: provision-infra
name: Provision Infrastructure
action: http:backstage:request
input:
method: POST
path: /api/platform/provision
body:
serviceName: $
database: $
cache: $
team: $
- id: register
name: Register in Catalog
action: catalog:register
input:
repoContentsUrl: $
catalogInfoPath: /catalog-info.yaml
output:
links:
- title: Repository
url: $
- title: Open in Catalog
url: $
From the developer’s perspective: fill in a form, click “Create,” and 3 minutes later they have a GitHub repo with CI/CD, a Kubernetes namespace, an optional database, RBAC, and their service registered in the catalog. No tickets. No waiting.
Infrastructure Self-Service with Crossplane
Crossplane turns your Kubernetes cluster into a universal infrastructure control plane. Platform teams define CompositeResourceDefinitions; product teams claim resources:
# Platform team defines: PostgresDatabase composite resource
apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
name: xpostgresdatabases.platform.myorg.com
spec:
group: platform.myorg.com
names:
kind: XPostgresDatabase
plural: xpostgresdatabases
claimNames:
kind: PostgresDatabase
plural: postgresdatabases
versions:
- name: v1alpha1
served: true
referenceable: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
size:
type: string
enum: [small, medium, large]
default: small
description: "small=2CPU/4GB, medium=4CPU/16GB, large=8CPU/32GB"
region:
type: string
default: ap-northeast-2
# Product team uses: just a claim
apiVersion: platform.myorg.com/v1alpha1
kind: PostgresDatabase
metadata:
name: payment-service-db
namespace: payments
spec:
size: medium
region: ap-northeast-2
writeConnectionSecretToRef:
name: payment-db-credentials
That’s it. The product team gets a managed PostgreSQL database in AWS RDS, with backups, monitoring, and credentials injected into their namespace — without knowing anything about Terraform or AWS IAM.
Measuring Platform Success
The most important metric for a platform team: Cognitive Load Reduction.
# Key platform metrics to track
PLATFORM_METRICS = {
# Developer Experience
"time_to_first_deployment": "Time from repo creation to first prod deploy (target: <1 day)",
"self_service_ratio": "% of infra requests fulfilled without tickets (target: >80%)",
"golden_path_adoption": "% of services using recommended templates (target: >70%)",
# Operational
"mttr": "Mean time to restore after incidents (platform-caused)",
"platform_slo_compliance": "% of platform components meeting their SLOs",
"deployment_frequency": "Deployments per team per day",
# Cost
"cost_per_deployment": "Infrastructure cost / total deployments",
"idle_resource_ratio": "% of provisioned resources actively used",
}
Collect these via developer surveys (quarterly NPS/developer satisfaction), platform telemetry, and DORA metrics.
Photo by Annie Spratt on Unsplash
Common Pitfalls and How to Avoid Them
1. Building for the platform team, not for developers Fix: Treat platform as a product. Run user research with developers. Ship based on their pain points, not your engineering interests.
2. The “big bang” portal launch Fix: Start with one golden path for your most common service type. Get 10 teams using it. Iterate. Then expand.
3. Mandating adoption Fix: Pave the road, don’t mandate it. If your golden path is better, teams will use it. If they don’t, your golden path needs work.
4. Platform team as gatekeeper Fix: Self-service or bust. If teams have to file tickets to use your platform, you’ve built a bureaucracy, not a platform.
5. No SLOs for the platform itself Fix: Your platform is production infrastructure. Treat it that way. Define and publish SLOs. Measure. Improve.
Key Takeaways
- Platform Engineering is DevOps evolved — the answer to “you build it, you run it” scaling problems
- The Golden Path is the core value proposition: self-service, well-lit, safe by default
- Backstage is the standard developer portal; software templates are its highest-value feature
- Crossplane enables infrastructure self-service via Kubernetes-native APIs
- Measure developer experience (NPS, time-to-deploy, self-service ratio) not just infrastructure metrics
- A platform team should have product managers, not just engineers
- Adoption is earned, not mandated — if developers don’t use your golden path, it’s not good enough yet
The best platform teams in 2026 are invisible. Developers don’t think about CI/CD, Kubernetes, or databases. They think about product features. That’s the goal.
References: CNCF Platform Engineering, Backstage.io Documentation, Crossplane Documentation, Team Topologies (Book)
이 글이 도움이 되셨다면 공감 및 광고 클릭을 부탁드립니다 :)
