Internal Developer Platforms: Killing Jira Tickets for Deployments
Building Internal Developer Platforms on Backstage + Terraform + ArgoCD for the 50-100 engineer company. The three templates that matter most, the service-catalogue discipline, and the measured impact: deploy frequency 5-6x, time-to-first-deploy hours instead of days.
If your engineers still open a Jira ticket to get a new environment, your platform team is the slowest path in your software delivery lifecycle. This article is the playbook for building self-service Internal Developer Platforms (IDPs) on Backstage, Terraform, and GitOps — the engineering investment that turns IT from "service request gatekeeper" to "platform product team".
Sized for the 30-100 engineer company that has outgrown ad-hoc tooling but does not need Spotify-scale platform engineering. Different angle from our platform engineering for 10-person teams article — that one is "what to do at 10 engineers"; this one is "what to do at 50-100 engineers when ad-hoc is no longer working".
The Jira-ticket-for-deployment anti-pattern
The friction signal: an engineer needs a new database, a new microservice, a new environment, a new staging cluster — and the path is:
- Open a Jira ticket
- Wait for IT / platform team to triage
- Have a meeting to clarify requirements
- Wait for the platform engineer to find time
- Receive the resource 2-7 days later
- Discover something is missing; loop back to step 2
The total elapsed time from "I need this" to "it works" is 5-15 business days. Multiply by the number of resource requests per engineer per month (typically 3-8 for an active product team), multiply by the number of engineers. The platform team becomes the velocity ceiling for the entire engineering organisation.
What an IDP actually is
An Internal Developer Platform is a product. Its users are engineers. Its features are self-service surfaces that wrap the underlying infrastructure (Kubernetes, AWS / Azure / GCP, databases, observability) into golden-path workflows.
Three primary surfaces:
- Discovery / catalogue. "What services exist? Who owns them? What is their on-call rotation? What is their SLO? Where is their documentation?"
- Self-service provisioning. "I want a new service. I want a new database. I want a staging environment. I want an experimental cluster."
- Operational visibility. "What is the build status? What deploys ran today? What alerts are firing? What is my service's error budget burn?"
The platform team builds the surfaces. The engineering teams consume them. The IT team operates them.
The Backstage decision (when to use it)
Backstage is Spotify's open-source IDP framework. It is also a non-trivial engineering investment. The decision to use it should be deliberate.
Use Backstage when:
- You have 30+ engineers contributing to 10+ services
- You have a dedicated platform team with 2+ FTE
- You need a single discovery surface across many services
- You want plugin extensibility for company-specific workflows
- You will commit to operating it (Backstage rewards commitment, punishes neglect)
Do not use Backstage when:
- You have under 20 engineers (use GitHub-as-portal + good README discipline)
- You do not have dedicated platform-team capacity (the operational cost will exceed the benefit)
- You want a polished out-of-the-box product (Backstage is a framework, not a product)
For the 50-100 engineer company we are addressing here, Backstage is usually the right answer. For smaller companies, see our platform engineering for small teams guidance.
The reference architecture
The IDP stack we deploy:
| Layer | Component | Purpose |
|---|---|---|
| Frontend | Backstage | Developer portal — discovery + provisioning + visibility |
| Service catalogue | Backstage catalog (entities defined in YAML in service repos) | Source of truth for "what exists + who owns it" |
| Templates / Scaffolder | Backstage software-templates | Self-service service creation, environment provisioning |
| Plugins | Kubernetes, Jenkins / GitHub Actions, ArgoCD, PagerDuty, Sentry, Grafana plugins | Operational visibility consolidated in one UI |
| Provisioning engine | Terraform via Atlantis or Terraform Cloud | The actual infrastructure changes |
| GitOps deployment | ArgoCD or Flux | Pulls Kubernetes manifests from Git; reconciles cluster state |
| Secrets | HashiCorp Vault or External Secrets Operator + cloud secret manager | Secret injection at deploy time |
| Identity | SSO via Entra ID / Okta + RBAC in Backstage | Who can do what |
The first three templates that matter most
An IDP without templates is a discovery portal that engineers stop visiting. The templates are the product. Build these three first:
Template 01: "Create a new backend service"
The engineer fills out a Backstage form: service name, owner team, language / framework, database needed (yes/no).
Backstage scaffolder:
- Creates a new GitHub repository from a service template
- Configures GitHub Actions CI/CD
- Creates the Terraform pull request in the platform-config repo (Kubernetes namespace, RBAC, network policies, etc.)
- If database requested: creates the Postgres / MySQL / MongoDB schema via Terraform with proper credentials in Vault
- Registers the service in the Backstage catalogue with default alerts, dashboards, runbook stub
- Posts in the engineer's Slack with "your service is ready"
End-to-end time: 8-15 minutes (most of it is Atlantis plan + apply). Manual equivalent: 2-5 business days.
Template 02: "Create a staging environment"
Spin up a full-stack ephemeral environment for testing. Engineer specifies: branch to deploy, expected lifetime (default 7 days, max 30).
Behind the scenes:
- Provision Kubernetes namespace with proper resource quotas
- Deploy all services from the catalogue targeting the specified branches
- Create scoped DNS entries (e.g.,
feature-branch-xyz.staging.client.com) - Inject test data from the standard fixtures
- Schedule auto-teardown after the lifetime expires
- Post a link to the engineer's PR with "your environment is ready at $url"
Time: 15-25 minutes. Cost: tracked per-environment with showback to the team. Auto-teardown prevents the "forgotten environments" cost-leak.
Template 03: "Onboard a new engineer"
The new-engineer workflow. HR creates the user in Entra; the IDP picks up the event and:
- Provisions GitHub Enterprise access + team membership
- Issues AWS / cloud account access via SSO with appropriate role binding
- Creates a personal sandbox namespace in the dev Kubernetes cluster
- Adds to the engineering Slack channels + standup rotation
- Sends the welcome email with links to: handbook, first-day tasks, buddy-engineer's contact
- Schedules the first-week orientation meetings
Time from HR-event to "engineer can deploy to staging on day 1": under 2 hours of automated work + the engineer's onboarding actions.
The service catalogue discipline
Backstage's catalogue is only as good as the data in it. The pattern that works:
The catalog-info.yaml that lives in every service repo
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: payment-service
description: |
Handles credit-card processing via Stripe.
Owned by the Payments team.
annotations:
github.com/project-slug: client-org/payment-service
pagerduty.com/integration-key: $PAGERDUTY_INTEGRATION_KEY
grafana/dashboard-url: https://grafana.client.com/d/payment-service
jaeger.io/service-name: payment-service
backstage.io/techdocs-ref: dir:.
tags:
- critical
- pci-scope
- typescript
spec:
type: service
lifecycle: production
owner: team-payments
system: commerce-stack
dependsOn:
- resource:postgres-payments-db
- component:auth-service
- component:notification-service
providesApis:
- payment-service-api
The discipline: every service has a catalog-info.yaml. CI fails if it is missing. New services cannot register without one. The catalogue stays honest because it lives next to the code, not in a separate database.
The GitOps integration
The IDP is the front door; ArgoCD is the deployment engine. The pattern:
- Engineer pushes code to feature branch → CI runs tests → green PR opened
- Reviewer approves → PR merges to main
- CI builds container image, pushes to registry, opens a PR against the platform-config repo updating the deployment manifest
- Platform-config PR runs the security + policy checks (OPA / Conftest)
- Reviewer approves → merges
- ArgoCD detects the change, reconciles the cluster, deploys the new image
- Backstage shows the deploy status in the service view
From merge to production: typically 5-12 minutes. Failed deploys roll back automatically via ArgoCD's reconciliation. The audit trail is the Git history.
The observability + on-call integration
Backstage's value compounds when it pulls operational data from the other tools the team uses:
- Grafana plugin: embeds the service's dashboard in the Backstage service view
- PagerDuty plugin: shows current on-call + recent incidents per service
- Sentry plugin: shows error trends + top exceptions for the service
- GitHub plugin: shows recent commits + open PRs + CI status
- ArgoCD plugin: shows deployment status across environments
An engineer investigating an incident opens the Backstage service page and sees everything in one place: who is on-call, what changed recently, what alerts are firing, what the dashboard looks like, what the runbook says. The context-switching reduction is the under-appreciated win.
The TechDocs piece
Backstage's TechDocs feature renders Markdown documentation that lives in service repos. The MkDocs Material theme produces decent-looking documentation without a separate documentation site to maintain.
The pattern: every service has a docs/ directory in its repo. TechDocs builds the docs as part of CI and serves them through Backstage. The docs are part of the codebase; updates happen in the same PR as the code change.
This solves the doc-rot problem we discuss in our AI-docs article: documentation that lives next to the code stays accurate longer than documentation that lives in a separate wiki.
The Terraform-via-Atlantis pattern
The provisioning engine. Engineers do not run terraform apply from their laptops. The flow:
- Backstage template creates a PR against the platform-config repo
- Atlantis runs
terraform planand posts the result as a PR comment - Reviewer reads the plan, approves the PR
- Atlantis runs
terraform applyafter merge, posts the result back to the PR - Backstage detects the new resource via the catalogue update + provisioning event
The benefits: every infrastructure change is reviewed. The audit trail is the PR history. The plan-as-PR-comment makes the change visible before it applies. The platform team can step in on risky changes without becoming the bottleneck on routine changes.
The "shadow IT" prevention angle
An IDP done well kills shadow IT not by policing but by making the legitimate path easier than the workaround. If "request a database via Backstage" takes 8 minutes and "spin up a personal RDS in someone's AWS account" takes 25 minutes plus invoicing fights, engineers choose the Backstage path.
The shadow-IT signal we track: engineering teams' personal AWS / GCP cost lines. Pre-IDP, these grow as engineers route around the platform. Post-IDP, they shrink as engineers consume the platform's better-instrumented alternatives.
The team composition
For a 50-100 engineer company adopting Backstage, the platform team is typically:
- 1 senior platform engineer (lead, Backstage-specialist)
- 2-3 platform engineers (templates, plugins, operate)
- 0.5 FTE site-reliability engineer (production + on-call)
- 0.25 FTE product / engineering-manager involvement
3.75-4.25 FTE total. Roughly 4-5% of the engineering headcount. The ratio is the cost of doing platform engineering at this scale; the alternative is every team rebuilding the same patterns badly.
The build vs buy decision (Backstage vs managed IDP)
Managed alternatives have matured:
| Option | Strengths | Trade-offs |
|---|---|---|
| Backstage (self-hosted, OSS) | Full control, free, plugin ecosystem | Real operational + engineering cost |
| Port.io | Hosted, faster setup, modern UX | Per-user pricing; less plugin depth |
| Cortex | Hosted, strong service-catalogue features | Pricing scales fast; less template depth |
| OpsLevel | Hosted, strong policy + maturity scoring | Pricing scales fast; opinionated |
| Roadie (managed Backstage) | Backstage without the operational cost | Per-user pricing; less customisation depth |
For the 50-100 engineer company: Backstage self-hosted if the team will commit to operating it, Roadie (managed Backstage) if not. The other managed options work but the per-user pricing scales unfavourably past ~150 engineers.
What we have learned from 4 IDP deployments
- The first template defines the product. Pick a template that solves a real pain point engineers feel weekly. The wrong first template produces an unloved Backstage instance.
- RBAC + ownership is half the engineering. "Who can create / approve / destroy" requires explicit policy. Backstage's RBAC is not free; design it carefully.
- Plugin maintenance compounds. Each plugin you add is an upgrade obligation. Choose plugins for the features your team actually uses, not for the demo.
- The IDP needs its own product roadmap. Treat it as a product with users (engineers). Survey them. Prioritise their pain. Ship measurable improvements.
- Migration from "Jira tickets" to "self-service" takes 6-9 months culturally. Engineers do not immediately trust the new path. Build trust by being faster + more reliable than the old way, every time.
The measurable impact
From a 65-engineer client 12 months post-IDP-rollout:
| Metric | Before | After |
|---|---|---|
| Time-to-first-deploy (new engineer) | 3-5 days | 1.5 hours median |
| Deployment frequency | ~12/day | ~67/day |
| Lead time (PR merge → production) | ~45 min | ~8 min median |
| New-service creation time | 3-7 business days | 12 minutes median |
| Ephemeral environment creation | Not possible (no template) | 15-25 minutes per env |
| Platform-team ticket queue | ~120 open tickets | ~15 open tickets |
| Shadow AWS spend (engineer personal accounts) | €8,400/quarter | €1,100/quarter |
The one paragraph version
If your engineers open Jira tickets to get environments, your platform is the bottleneck. The fix is an Internal Developer Platform: Backstage as the front door, Terraform via Atlantis as the provisioning engine, ArgoCD for GitOps deployments, plugins consolidating observability + on-call + CI status. The first three templates (new service, ephemeral environment, engineer onboarding) define the product. Service catalogue discipline (catalog-info.yaml in every repo, CI-enforced) keeps the data honest. Platform-team composition: 3.75-4.25 FTE for a 50-100 engineer company. Measured impact: time-to-first-deploy drops from days to hours; deployment frequency 5-6x; shadow-IT spend collapses; platform-team ticket queue shrinks 85%. Build vs buy: Backstage self-hosted if committed to operate, Roadie (managed Backstage) if not.
If you want this designed + deployed + handed over, that is the engagement shape under our Intelligent Workflow Automation + Azure Cloud Infrastructure services. The deeper "what to do at 10 engineers" guidance is in our companion platform engineering for small teams article.