Back to Articles
📄
platform engineeringinternal developer platformGitOpsArgo CDBackstageservice catalogCI/CDobservability

Platform Engineering and Internal Developer Platforms

Onboarding new engineers stalls for weeks because tooling and access aren’t automated. A self‑service internal developer platform gives them a golden path to provision services, CI/CD and observability in minutes, turning weeks of setup into a single workday.

Platform Engineering and Internal Developer Platforms

In unstandardized engineering organizations, new hires spend weeks navigating manual environment configuration, permission requests, and fragmented CI pipelines. This onboarding latency represents an infrastructure deficiency: self-service Internal Developer Platforms (IDPs) automate ephemeral workspace provisioning and RBAC assignment, enabling developers to merge verified commits on their first day.

Platform engineering is about building and maintaining the internal infrastructure, tools, and workflows that allow product teams to reliably release software without becoming infrastructure experts. An Internal Developer Platform (IDP) is the product that platform engineering teams create.

What an IDP Actually Is

An IDP isn't a single tool; it's a curated set of capabilities such as provisioning, continuous integration and continuous deployment (CI/CD), secrets management, observability, and deployment, all accessible through a self‑service interface that product teams can use without needing to file tickets or wait for the platform team.

The key concept here is self‑service. If a platform requires a ticket to provision a new service, it’s not a platform, it's a managed service with additional steps. A true platform lets developers provision new services, set up CI/CD pipelines, configure secrets, and deploy to staging in just 30 minutes. That speed means a feature can move from code commit to a testable environment within a single workday, eliminating idle time.

IDP capabilities (typical):

Self-service portal (Backstage)
    ├── Service catalog        - discover existing services, APIs, docs
    ├── Software templates     - scaffold new services with golden-path defaults
    ├── Environment provisioning - create dev/staging environments on demand
    └── Deployment UI          - deploy, rollback, view logs

CI/CD (GitHub Actions + Argo CD)
    ├── Build pipelines        - lint, test, build, scan, push image
    ├── GitOps deployment      - Argo CD syncs cluster state from Git
    └── Progressive delivery   - canary, blue/green via Argo Rollouts

Infrastructure (Terraform + Crossplane)
    ├── Cloud resources        - databases, queues, storage via self-service
    └── Kubernetes namespaces  - isolated environments per team/service

Observability (OpenTelemetry + Grafana)
    ├── Auto-instrumentation   - traces and metrics without team effort
    └── Baseline dashboards    - RED metrics for every service by default

Security (built in, not bolted on)
    ├── Image scanning         - Trivy in every pipeline
    ├── Secret management      - Vault or AWS Secrets Manager, not env vars
    └── Policy enforcement     - OPA/Kyverno admission controllers

The Golden Path

The "golden path" is the predefined, pre‑configured route through the platform that works well for most teams most of the time. It isn't the only path, teams can deviate when they have a good reason, but it is the path that is maintained, documented, and supported.

A golden path for a new service might include:

  • a service template that scaffolds the repository with the right structure, CI pipeline, Dockerfile, and Helm chart;
  • a CI pipeline that runs linting, testing, security scanning, and SBOM generation automatically;
  • a GitOps deployment that uses Argo CD to sync the Helm chart to the cluster;
  • auto‑instrumentation for OpenTelemetry traces and metrics; and
  • a baseline Grafana dashboard that is provisioned automatically.

The developer's job is to write the business logic. The platform's job is to make everything else work seamlessly and by default.

# Backstage software template: scaffold a new Node.js service
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
  name: nodejs-service
  title: Node.js Microservice
spec:
  parameters:
    - title: Service details
      properties:
        name:
          type: string
          description: Service name (kebab-case)
        owner:
          type: string
          description: Team owning this service

  steps:
    - id: fetch
      action: fetch:template
      input:
        url: ./skeleton
        values:
          name: ${{ parameters.name }}
          owner: ${{ parameters.owner }}

    - id: publish
      action: publish:github
      input:
        repoUrl: github.com?repo=${{ parameters.name }}&owner=myorg

    - id: register
      action: catalog:register
      input:
        repoContentsUrl: ${{ steps.publish.output.repoContentsUrl }}

Backstage: The Service Catalog

Backstage, an open‑source project originally developed by Spotify and now part of the Cloud Native Computing Foundation (CNCF), is the most widely adopted foundation for IDPs. It offers a service catalog, software templates, and a plugin ecosystem.

The service catalog is the most immediately useful component. It answers the fundamental question that every engineer in a large organization eventually asks: "What services exist, who owns them, where is the documentation, and what does this service depend on?" By surfacing this information centrally, the catalog eliminates guesswork and reduces the time spent hunting for owners or missing runbooks.

# catalog-info.yaml - every service registers itself
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: order-service
  description: Handles order creation, modification, and cancellation
  annotations:
    github.com/project-slug: myorg/order-service
    grafana/dashboard-selector: "service=order-service"
    pagerduty.com/service-id: P1234567
spec:
  type: service
  lifecycle: production
  owner: team-commerce
  system: commerce-platform
  dependsOn:
    - component:inventory-service
    - resource:orders-database
  providesApis:
    - order-api

With every service registered in the catalog, a new engineer can discover the entire system, understand dependencies, find runbooks, and reach the owning team, without needing to ask anyone.

GitOps with Argo CD

GitOps is the practice of using Git as the single source of truth for infrastructure and application state. Argo CD is a Kubernetes‑native GitOps controller that continuously reconciles the cluster state with the desired state declared in Git.

Developer pushes to main
    ↓
CI pipeline: test → build → push image → update Helm values in Git
    ↓
Argo CD detects Git change
    ↓
Argo CD applies Helm chart to cluster
    ↓
Cluster state matches Git state

The benefit is clear: auditability and rollback. Every deployment is a Git commit. Rolling back is a Git revert. The cluster state is always inspectable in Git, not just in the cluster. This transparency lets us trace exactly which code change introduced a failure and revert it with a single command.

# Argo CD Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: order-service
  namespace: argocd
spec:
  project: commerce
  source:
    repoURL: https://github.com/myorg/gitops-config
    targetRevision: HEAD
    path: services/order-service/overlays/production
  destination:
    server: https://kubernetes.default.svc
    namespace: commerce-production
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

The "How Much Platform Is Enough?" Debate

Platform engineering has a common failure mode: over‑engineering. A platform team that builds a sophisticated IDP that product teams don't use has wasted significant effort. The platform must solve real problems that product teams actually have, not just problems that the platform team finds interesting. When we align the roadmap with pain points reported by developers, the platform delivers measurable productivity gains.

The practical test is adoption. If product teams voluntarily choose the golden path, without being required to, the platform is providing value. If teams are working around the platform, the platform has a usability problem.

Common failure modes include:

  • Too much abstraction: The platform hides so much that teams cannot debug problems when the abstraction leaks.
  • Too slow to evolve: The platform becomes a bottleneck because adding new capabilities requires a ticket to the platform team.
  • Not treating the platform as a product: The platform team builds what they think teams need, not what teams actually ask for. Product management discipline applies to internal platforms as well.

The right amount of platform is the minimum that lets product teams ship reliably without becoming infrastructure experts. That minimum is higher than most organizations currently have, and lower than some platform teams want to build.

Why Voluntary Adoption Is the Only Reliable Signal

Platform teams often measure success by the number of services onboarded or the features shipped. Neither is a reliable signal. A team can be forced onto a platform by policy and still work around it for anything that matters. Features can be built that no one uses.

Voluntary adoption is the only signal that cannot be gamed. When a team chooses the golden path because it is faster and less painful than the alternative, the platform is working. When teams route around it, maintaining their own CI scripts, their own deployment tooling, their own dashboards, the platform has a product problem, not a communication problem. The fix is to talk to those teams and understand what is missing, not to mandate adoption.

This is why platform engineering borrows from product management: user research, feedback loops, and prioritization based on actual pain points rather than assumed ones.

Sources & References

  1. [1]
  2. [2]
  3. [3]
  4. [4]
  5. [5]
  6. [6]
  7. [7]
  8. [8]
  9. [9]
  10. [10]

Comments (0)

Loading comments...