Learnixo
Back to blog
Cloud & DevOpsadvanced

Platform Engineering: The Complete Guide for 2026

Everything you need to know about platform engineering — Internal Developer Platforms, golden paths, GitOps, Backstage, Crossplane, service mesh, policy as code, and how to build a platform your developers actually love.

LearnixoJune 9, 202610 min read
Platform EngineeringIDPGitOpsBackstageKubernetesDevOpsDevExCareer
Share:𝕏

What Is Platform Engineering?

Platform engineering is the discipline of designing, building, and operating Internal Developer Platforms (IDPs) — self-service layers on top of infrastructure that let product teams ship software without becoming Kubernetes or cloud experts.

The simplest framing: platform engineering is DevOps at scale.

When you have 5 teams, one senior DevOps engineer can help everyone. When you have 50 teams, you can't embed a DevOps expert in every squad. You build a platform instead — a product that encodes the best practices and automates the toil.


Platform Engineering vs DevOps vs SRE

These three roles are often confused. Here's how they differ:

| Role | Focus | Customers | |------|-------|-----------| | DevOps | Cultural practice: shared ownership of delivery | Dev + Ops together | | SRE | Reliability engineering: SLOs, error budgets, on-call | Production systems | | Platform Engineering | Building self-service infrastructure tooling | Internal developers |

Platform engineering is the operationalisation of DevOps. It answers: "How do we scale DevOps practices to 200 developers without creating a centralized bottleneck?"


The Internal Developer Platform (IDP)

An IDP is not a single tool — it's a curated set of capabilities with a self-service interface.

The core pillars of an IDP:

  1. Deployment pipeline — automated CI/CD with opinionated defaults (GitHub Actions golden workflow)
  2. Infrastructure self-service — provision databases, queues, caches without filing tickets
  3. Environment management — spin up dev/staging environments on demand
  4. Secrets management — inject credentials securely (Vault + External Secrets Operator)
  5. Service catalog — discover services, APIs, dependencies, owners (Backstage)
  6. Observability — metrics, logs, traces pre-configured for every new service
  7. Security & policy — compliance checks automated into the pipeline and cluster admission

What an IDP is NOT:

  • A Confluence page with documentation
  • A Jira board for infra tickets
  • A bespoke internal tool that only one person understands

The Platform-as-a-Product Mindset

The single most important shift in platform engineering: treat your developers as customers.

This means:

  • User research: talk to your developers. What causes the most friction? What takes the longest?
  • Product backlog: prioritize with a product manager, not just based on what's technically interesting
  • Adoption metrics: track who uses the platform, what they bypass, and why
  • NPS surveys: quarterly developer satisfaction surveys. If your NPS is negative, fix the platform
  • Roadmap transparency: developers should know what's coming and why

The platform death spiral is what happens when you build without this mindset:

Built features nobody asked for
→ Poor adoption
→ Management questions value
→ Team gets cut
→ Platform degrades
→ Teams go back to manual chaos

Avoid it by building things developers actually want.


Team Topologies: How to Structure a Platform Team

Team Topologies by Skelton & Pais defines four team types:

  • Stream-Aligned: delivers product features (your product teams)
  • Platform: provides self-service infrastructure (the platform team)
  • Enabling: temporarily helps teams adopt new capabilities (e.g., "security guild")
  • Complicated Subsystem: deep specialist work (e.g., the team that owns your payment processor integration)

Interaction modes for platform teams:

  • X-as-a-Service: the target state — developers consume the platform like an API, minimal back-and-forth
  • Collaboration: short burst when adopting something new, then reduce interaction

A platform team that constantly does tickets for other teams is not running X-as-a-Service — it's a bottleneck pretending to be a platform.


Golden Paths: Paved Roads Without Cages

A golden path is an opinionated, well-maintained path for the most common use case — "here's how we deploy a microservice", "here's how you get a database".

The key design principle: the golden path must be easy, not mandatory.

If you mandate it without an escape hatch, teams will work around it. Instead:

  • Make the golden path so much better than the alternative that nobody wants to escape
  • Document escape hatches explicitly for legitimate edge cases
  • Update the golden path when you see teams consistently bypassing parts of it — that's feedback

Typical golden path scope:

New service → GitHub template (Backstage scaffolder)
  → Dockerfile + docker-compose
  → GitHub Actions workflow (lint, test, build, scan)
  → ArgoCD application manifest
  → Kubernetes Deployment + Service + HPA
  → Grafana dashboard (auto-provisioned)
  → PagerDuty alert routing
  → Backstage catalog entry

A developer runs one command (or fills one Backstage form) and all of this is wired up.


GitOps with ArgoCD

GitOps means Git is the single source of truth for desired cluster state. An operator runs in the cluster and continuously reconciles actual state toward what's in Git.

Why GitOps over push-based CI/CD:

| Traditional Push | GitOps Pull | |-----------------|-------------| | CI pipeline kubectl apply directly | Operator reads Git, applies changes | | Drift is invisible — someone kubectl edits something | Drift is detected and alerted | | Audit trail is in CI logs | Audit trail is in Git history | | Credentials in CI pipeline | No cluster credentials in CI |

ArgoCD key concepts:

YAML
# ArgoCD Application  declare desired state
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-service
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/org/gitops-repo
    targetRevision: HEAD
    path: apps/my-service
  destination:
    server: https://kubernetes.default.svc
    namespace: my-service
  syncPolicy:
    automated:
      prune: true      # delete resources removed from Git
      selfHeal: true   # auto-sync on drift detection

The App-of-Apps pattern lets you manage all applications as a single ArgoCD application:

gitops-repo/
├── apps/
│   ├── app-of-apps.yaml      # root application
│   ├── my-service/
│   │   ├── deployment.yaml
│   │   └── service.yaml
│   └── another-service/
│       └── ...

Production tip: Use selfHeal: false in production — review sync in ArgoCD UI before applying. Automated sync is fine for dev/staging.


Backstage: Developer Portal

Backstage (open-sourced by Spotify) is the most popular choice for an IDP frontend.

Core capabilities:

  • Software Catalog: every service, API, library, and website registered with owner, dependencies, runbooks
  • Scaffolder: project templates — teams fill a form and get a fully wired-up repo + Kubernetes manifests + CI/CD
  • TechDocs: docs-as-code, rendered alongside the catalog entry
  • Plugins: GitHub Actions, Kubernetes, Grafana, PagerDuty, Dynatrace — hundreds available

catalog-info.yaml registers a service:

YAML
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: payment-service
  description: Handles payment processing for all orders
  annotations:
    github.com/project-slug: org/payment-service
    grafana/dashboard-selector: "payment"
    pagerduty.com/service-id: P123456
  tags:
    - backend
    - payments
    - java
spec:
  type: service
  lifecycle: production
  owner: team-payments
  system: checkout
  dependsOn:
    - resource:default/payments-database
    - component:default/fraud-detection-service
  providesApis:
    - payment-api-v2

Custom plugins let you embed any internal tool into Backstage — incident timeline, feature flags, cost per service, deployment history.


Crossplane: Self-Service Infrastructure

Crossplane lets developers provision cloud resources (RDS, S3, Azure ServiceBus) using Kubernetes CRDs — no Terraform state files, no separate tooling.

How it works:

Developer applies a resource claim
  → Crossplane Composite Resource resolves it
  → Provider creates the actual cloud resource
  → Connection details stored as K8s Secret
  → External Secrets Operator syncs to app namespace

Example: self-service PostgreSQL

YAML
# Developer creates this claim
apiVersion: platform.example.com/v1alpha1
kind: PostgreSQLInstance
metadata:
  name: my-app-db
  namespace: team-alpha
spec:
  parameters:
    storageGB: 20
    version: "15"
    environment: staging
  writeConnectionSecretToRef:
    name: my-app-db-credentials

Behind the scenes, the platform team's Composite Resource Definition (XRD) translates this into an AWS RDS instance with proper VPC, subnet, backup, and encryption settings — none of which the developer needs to understand.

Crossplane vs Terraform:

| Crossplane | Terraform | |-----------|-----------| | Kubernetes-native, CRDs | CLI-driven, HCL | | Continuous reconciliation (drift detection) | terraform plan on demand | | Ideal for self-service developer workflows | Better for complex infra graphs | | No state file management | State file in S3/Terraform Cloud |


Service Mesh: Istio and Linkerd

A service mesh adds a sidecar proxy to every Pod, giving you:

  • mTLS between all services (zero-trust networking)
  • Traffic management (canary, weighted routing, retries, circuit breaking)
  • Observability (per-connection metrics, distributed tracing, access logs)

Istio vs Linkerd:

| | Istio | Linkerd | |--|-------|---------| | Proxy | Envoy (C++) | Linkerd2-proxy (Rust) | | Resource overhead | Higher | Lower | | Complexity | High | Low | | Traffic management | Advanced (VirtualService, DestinationRule) | Basic | | When to use | Advanced routing, large platform teams | mTLS + observability, simpler ops |

Istio canary release example:

YAML
# Send 90% traffic to v1, 10% to v2
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: checkout
spec:
  hosts:
    - checkout
  http:
    - route:
        - destination:
            host: checkout
            subset: v1
          weight: 90
        - destination:
            host: checkout
            subset: v2
          weight: 10

Recommendation: Start with Linkerd. Upgrade to Istio if you need advanced traffic management.


Policy as Code: Kyverno and OPA

Policy as Code enforces compliance rules automatically in the admission webhook — before anything reaches the cluster.

Kyverno (Kubernetes-native, YAML policies):

YAML
# Require every Deployment to have resource limits
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-resource-limits
spec:
  validationFailureAction: Enforce
  rules:
    - name: check-container-resources
      match:
        any:
          - resources:
              kinds: [Deployment]
      validate:
        message: "Resource limits are required for all containers."
        pattern:
          spec:
            template:
              spec:
                containers:
                  - resources:
                      limits:
                        memory: "?*"
                        cpu: "?*"

OPA/Gatekeeper is more powerful (Rego language) but has a steeper learning curve. Use OPA when you need policy across Kubernetes, Terraform, and APIs.

Run policies in audit mode first — see what would fail before enforcing.


Observability as a Platform Service

Developers shouldn't configure their own metrics, logging, or tracing pipelines. The platform provides it automatically.

The OpenTelemetry Collector is the central hub:

Services (auto-instrumented) → OTel Collector → Prometheus (metrics)
                                              → Loki (logs)
                                              → Tempo (traces)
                                              → Grafana (visualization)

What's automatic (zero-config):

  • Infrastructure metrics: CPU, memory, network per Pod (kube-state-metrics + node-exporter)
  • Access logs: via Istio or ingress controller
  • Distributed traces: OTel auto-instrumentation sidecar
  • Pre-built Grafana dashboards: RED metrics (Rate, Errors, Duration) per service

What's opt-in:

  • Custom business metrics
  • SLO/SLA alerting
  • Continuous profiling (Pyroscope)

DORA Metrics: Measuring Platform Impact

The four DORA metrics measure software delivery performance:

| Metric | Elite | High | Medium | Low | |--------|-------|------|--------|-----| | Deployment Frequency | Multiple/day | Weekly | Monthly | Monthly/less | | Lead Time for Changes | < 1 hour | 1 day | 1 week | 1 month | | Change Failure Rate | < 5% | 10% | 15% | > 15% | | Mean Time to Restore | < 1 hour | < 1 day | < 1 week | > 1 week |

Track these before and after platform investments to demonstrate ROI.

Beyond DORA — developer experience metrics:

  • Onboarding time: how long until a new hire ships their first production change
  • Self-service rate: what % of infra requests were handled without a platform ticket
  • CI/CD P95 duration: slow pipelines kill developer flow
  • Platform NPS: quarterly survey, target > 30

The Platform Team's North Star

Platform engineering succeeds when product teams don't think about infrastructure.

They just code. They push to Git. It deploys, it's observable, it's secure, and they get paged when something breaks.

That's the goal. Every decision — what to automate, what to make self-service, what to put in the golden path — should be evaluated against it.

Build the platform your developers deserve.

Enjoyed this article?

Explore the Cloud & DevOps learning path for more.

Found this helpful?

Share:𝕏

Leave a comment

Have a question, correction, or just found this helpful? Leave a note below.