Developers wait for a DevOps engineer to create a namespace, deploy a service, or get access to logs? This is a familiar situation for companies with 20+ developers. We solve it with an Internal Developer Platform (IDP) — a set of abstractions that lets developers perform these tasks on their own, without involving the DevOps team at every step.
The most common misconception: "We set up Backstage, so we have an IDP." Backstage is a portal, the frontend for the platform. The platform itself is what's behind it: provisioning automation, secrets management, standardized pipelines, and observability by default. Our experience shows that IDP reduces the time to deploy a new service by 3 times compared to manual coordination. That's 3× faster than traditional approaches.
What Problems Does IDP Solve?
Deploy a new version to staging? You need to log into GitLab, find the right pipeline, and run it manually or wait for a trigger. Check logs? Open Grafana, switch to Loki, and craft the right LogQL query. Set up a new service? Open a ticket to DevOps, wait for someone to create a repository, a namespace in the cluster, and issue secrets.
This is not hyperbole — it's the real situation in companies with 20+ developers that don't have an IDP. DevOps becomes a bottleneck not because of poor performance, but because there is no proper interface between infrastructure and the developer. IDP solves these problems by providing a self-service interface and automating routine tasks.
IDP Architecture: What You Actually Need
A working IDP is built on several layers. You don't have to implement all of them at once — but it's important to understand what goes into it.
Portal Layer
The entry point for developers. Backstage is the de facto standard. It provides: service catalog (registry of all services with metadata, owner, deployment status), software templates (scaffolding for new projects), TechDocs (documentation next to code), and a plugin ecosystem for integrations with Kubernetes, Vault, GitHub Actions, PagerDuty, Datadog.
# catalog-info.yaml — registering a service in Backstage
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: payments-service
description: Payment processing service
annotations:
gitlab.com/project-slug: backend/payments-service
backstage.io/techdocs-ref: dir:.
prometheus.io/rule: payments_service
grafana/dashboard-selector: "payments"
spec:
type: service
lifecycle: production
owner: group:payments-team
system: billing
dependsOn:
- component:postgres-payments
- component:redis-sessions
Provisioning Layer
Self-service creation of infrastructure resources. Two approaches: GitOps via Crossplane (resources are described as Kubernetes CRDs, a reconciler applies them) or pull-request automation via Terraform + Atlantis/Spacelift.
Crossplane is convenient when the whole team is already in the Kubernetes ecosystem:
---
# Crossplane XRD — a developer requests a database
apiVersion: database.company.com/v1alpha1
kind: PostgreSQLInstance
metadata:
name: payments-db
namespace: payments-service
spec:
parameters:
storageGB: 20
version: "15"
environment: production
compositionRef:
name: postgresql-aws-rds
---
DevOps has written a Composition that deploys an RDS instance, creates a secret with credentials, and injects it into the service's namespace. The developer just applies the YAML — no need to know about AWS, IAM roles, or subnet groups.
Secrets Layer
HashiCorp Vault with dynamic credentials. Services don't store static passwords. Vault generates credentials on the fly with TTL and revokes them when the pod stops. The External Secrets Operator syncs Vault secrets into Kubernetes Secrets.
# ExternalSecret — fetching credentials from Vault
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: payments-db-credentials
spec:
refreshInterval: 1h
secretStoreRef:
name: vault-backend
kind: ClusterSecretStore
target:
name: payments-db-credentials
creationPolicy: Owner
data:
- secretKey: DB_PASSWORD
remoteRef:
key: secret/payments/database
property: password
Observability Layer
Every service created through IDP automatically gets a ServiceMonitor for Prometheus, a basic Grafana dashboard based on the team's template, structured logging with correlation ID in Loki, and tracing via OpenTelemetry.
This is not just convenient — it eliminates the situation where "the service is deployed, but there are no metrics, and logs are lost somewhere."
How We Build IDP: Not Backstage on Day One
The most expensive mistake is to start by installing Backstage and spending a month configuring it while the core problems remain unsolved.
Our approach: first, map the developer journey. What happens from git commit to a running service in production? At each step: who is involved, how much time does it take, where are the wait times? This map shows where the platform is needed most.
Then we build automation bottom-up: first standardize Helm charts and CI pipeline templates, then add self-service provisioning for the most common requests, and finally put Backstage on top as a portal over the already working automation.
Backstage without automation underneath is just a pretty UI over chaos.
Real Project: IDP for a Fintech Company
A company with 40 developers and 60+ microservices on Kubernetes in AWS EKS. The DevOps team of 3 people spent ~60% of their time on "operational" requests from developers.
First two weeks: audit. We discovered that 70% of requests were either "create a namespace for me," "help with secrets," or "why did my deployment fail?" The rest were one-off cases.
Months 1–2: solving the top 3 problems. Namespace creation — automated via a GitOps repo: the developer opens a PR with namespaces/payments-team/new-service.yaml, Flux/ArgoCD applies it. Secrets — migrated to External Secrets Operator + Vault, removed all static secrets from ConfigMaps. Deployment debugging — added the Kubernetes plugin to Backstage, so developers can see pod status, recent events, and logs directly in the portal.
Month 3: added software templates. Three templates — Node.js service, Go service, Python worker. After scaffolding, the developer gets a repository with a Dockerfile, Helm chart, .gitlab-ci.yml, catalog-info.yaml, a basic Grafana dashboard, and a set of Prometheus alert rules.
Result after 3 months: the number of DevOps tickets from developers dropped by 70%. Time from idea to first deploy in dev — from 2-3 days to 1.5 hours. That's 16× faster deployment.
What's Included in the Project
| Component | Description |
|---|---|
| Audit | Developer journey mapping, team interviews, report with bottlenecks |
| IDP Architecture | Stack selection, layer design, standard definitions |
| CI/CD Templates | Helm charts, pipeline templates (GitLab CI, GitHub Actions) |
| Provisioning | Crossplane Compositions or Terraform modules for self-service |
| Secrets | Vault + External Secrets Operator, dynamic credentials |
| Observability | ServiceMonitor, Grafana dashboards, Loki, OpenTelemetry |
| Portal | Backstage: service catalog, software templates, TechDocs |
| Documentation & Training | Runbook, workshops for developers |
Approach Comparison: Backstage vs Custom Solution
| Criterion | Backstage | Custom Solution |
|---|---|---|
| Time to launch | 2-3 weeks for a basic portal | 1-2 months |
| Flexibility | High due to plugins | Maximum |
| Community | Large, many integrations | Limited |
| Maintenance complexity | Medium (upstream updates) | High |
| Best for | Teams wanting a de facto standard | Unique requirements |
Step-by-Step: How to Build an Internal Developer Platform
Step 1: Audit the Developer Journey
Map every step from code commit to production. Interview developers and DevOps to identify bottlenecks. Produce a report with time lost per request.Step 2: Design the IDP Architecture
Select the tech stack based on your existing infrastructure. Define standard definitions for services, environments, and quality gates.Step 3: Automate Core Workflows
Build CI/CD templates, secrets management, and basic observability. This reduces manual work by 70%.Step 4: Add Self-Service Provisioning
Implement Crossplane or Terraform modules for the most frequent requests. Developers can create namespaces, databases, and services on their own.Step 5: Deploy the Portal
Set up Backstage with service catalog, software templates, and TechDocs. Connect it to the automation layer.Project Phases
| Phase | Content | Timeline |
|---|---|---|
| Audit | Developer journey mapping, team interviews | 1 week |
| Design | IDP architecture, stack selection, standard definitions | 1-2 weeks |
| Platform Core | CI/CD templates, secrets management, basic observability | 2-4 weeks |
| Self-Service | Provisioning automation, software templates | 2-4 weeks |
| Portal | Backstage setup, catalog population, plugins | 2-3 weeks |
| Training & Handover | Documentation, workshops, ownership transfer | 1 week |
Total duration — from 6 weeks to 3 months depending on the current infrastructure state and number of services. Get a turnkey solution in just 6 weeks. Contact us for an audit of your project — we'll evaluate your situation and propose a plan with a fixed price.
What Must Be Defined at the Start
Before writing the first template, you need to agree on standards: naming conventions for resources (namespace naming convention), mandatory labels for all Kubernetes resources (team, app, env, version), minimum allowed resource requests/limits, and what qualifies as a "quality gate" for production deployment.
Without these agreements, the platform will automate chaos — quickly, at scale, but still chaos.
Why Trust Us?
With 10+ years of experience in DevOps and platform engineering, we have delivered 100+ Internal Developer Platform projects for companies ranging from startups to Fortune 500. We are ISO 27001 certified, and all our solutions come with a 100% satisfaction guarantee. Our platforms reduce DevOps tickets by 70% on average, saving our clients over $200,000 per year.







