Internal Developer Portal(IDP)とは
Internal Developer Portal(IDP)は、開発者が必要とするツール、サービス、ドキュメント、インフラストラクチャへのアクセスを一元化するプラットフォームです。2025年、Platform Engineeringの台頭とともに、IDPは現代のソフトウェア開発組織において不可欠な存在となりました。
IDPが解決する課題
flowchart TB
subgraph Before["従来の開発環境"]
Dev1["開発者"] --> Tool1["CI/CD"]
Dev1 --> Tool2["監視"]
Dev1 --> Tool3["ドキュメント"]
Dev1 --> Tool4["インフラ"]
Dev1 --> Tool5["API管理"]
style Tool1 fill:#f96
style Tool2 fill:#9cf
style Tool3 fill:#fc9
style Tool4 fill:#9f9
style Tool5 fill:#f9f
end
subgraph After["IDP導入後"]
Dev2["開発者"] --> IDP["Internal Developer Portal"]
IDP --> Service1["統合されたサービス"]
IDP --> Service2["一元化された情報"]
IDP --> Service3["セルフサービス"]
style IDP fill:#4a9eff
end
現代の開発チームは、数十から数百のツールやサービスを日常的に使用しています。これらが分散していると、以下の問題が発生します:
- 認知負荷の増大: ツールごとに異なるUIと操作方法
- オンボーディングの長期化: 新メンバーが生産的になるまでに数週間〜数ヶ月
- サービスの発見困難: 「あのAPIは誰が管理している?」という質問の繰り返し
- 標準化の欠如: チームごとに異なるベストプラクティス
Backstageとは
Backstageは、Spotifyが2016年に内部開発し、2020年にCNCF(Cloud Native Computing Foundation)に寄贈したオープンソースのInternal Developer Portalプラットフォームです。2024年にCNCFのGraduatedプロジェクトとなり、2025年現在、IDPのデファクトスタンダードとして広く採用されています。
Backstageのコアコンセプト
# Backstageの4つの柱
backstage_pillars:
software_catalog:
description: "組織内の全ソフトウェア資産を一元管理"
features:
- サービス、API、リソースの登録
- オーナーシップの明確化
- 依存関係の可視化
- メタデータ検索
software_templates:
description: "ベストプラクティスに基づくプロジェクト生成"
features:
- ゴールデンパステンプレート
- 自動化されたセットアップ
- 一貫した構成
techdocs:
description: "コードと共存するドキュメント"
features:
- Docs-as-Code
- 自動生成・更新
- 検索可能
plugins:
description: "拡張可能なプラグインシステム"
features:
- 200以上の公式・コミュニティプラグイン
- カスタムプラグイン開発
- 既存ツールとの統合
Backstageのインストールと基本設定
環境構築
# Backstageアプリの作成
npx @backstage/create-app@latest
# プロジェクト名を入力
? Enter a name for the app [my-backstage-app]
# ディレクトリに移動して起動
cd my-backstage-app
yarn dev
app-config.yaml の基本設定
# app-config.yaml
app:
title: "TechCorp Developer Portal"
baseUrl: http://localhost:3000
support:
url: https://support.techcorp.com
items:
- title: "Slack Channel"
icon: chat
links:
- url: https://techcorp.slack.com/channels/platform-support
title: "#platform-support"
organization:
name: "TechCorp"
backend:
baseUrl: http://localhost:7007
listen:
port: 7007
csp:
connect-src: ["'self'", "http:", "https:"]
cors:
origin: http://localhost:3000
methods: [GET, HEAD, PATCH, POST, PUT, DELETE]
credentials: true
database:
client: pg
connection:
host: ${POSTGRES_HOST}
port: ${POSTGRES_PORT}
user: ${POSTGRES_USER}
password: ${POSTGRES_PASSWORD}
integrations:
github:
- host: github.com
token: ${GITHUB_TOKEN}
gitlab:
- host: gitlab.com
token: ${GITLAB_TOKEN}
auth:
environment: development
providers:
github:
development:
clientId: ${AUTH_GITHUB_CLIENT_ID}
clientSecret: ${AUTH_GITHUB_CLIENT_SECRET}
catalog:
import:
entityFilename: catalog-info.yaml
pullRequestBranchName: backstage-integration
rules:
- allow: [Component, System, API, Resource, Location, Domain, Group, User]
locations:
# 組織のサービスカタログ
- type: url
target: https://github.com/techcorp/backstage-catalog/blob/main/all-services.yaml
rules:
- allow: [Component, System, API]
# チームと組織構造
- type: url
target: https://github.com/techcorp/backstage-catalog/blob/main/org.yaml
rules:
- allow: [Group, User]
Software Catalog
Software Catalogは、Backstageの中核機能です。組織内のすべてのソフトウェア資産(サービス、ライブラリ、API、インフラストラクチャなど)を一元的に管理・検索できます。
catalog-info.yaml によるサービス登録
# catalog-info.yaml
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: payment-service
description: "決済処理を行うマイクロサービス"
title: "Payment Service"
annotations:
# GitHub統合
github.com/project-slug: techcorp/payment-service
# CI/CD統合
backstage.io/techdocs-ref: dir:.
jenkins.io/job-full-name: techcorp/payment-service/main
# 監視統合
grafana/dashboard-selector: "payment-service"
prometheus.io/alert: "payment_service_alerts"
# PagerDuty統合
pagerduty.com/service-id: P123ABC
# SonarQube統合
sonarqube.org/project-key: techcorp_payment-service
tags:
- java
- spring-boot
- payments
- critical
links:
- url: https://payment-service.techcorp.internal
title: Internal Endpoint
icon: dashboard
- url: https://grafana.techcorp.internal/d/payment
title: Grafana Dashboard
icon: dashboard
- url: https://runbook.techcorp.internal/payment-service
title: Runbook
icon: docs
spec:
type: service
lifecycle: production
owner: team-payments
system: payment-platform
dependsOn:
- component:user-service
- resource:payment-database
- resource:redis-cache
providesApis:
- payment-api
consumesApis:
- user-api
- notification-api
API定義
# payment-api.yaml
apiVersion: backstage.io/v1alpha1
kind: API
metadata:
name: payment-api
description: "決済処理API"
tags:
- rest
- payments
spec:
type: openapi
lifecycle: production
owner: team-payments
system: payment-platform
definition:
$text: ./openapi/payment-api.yaml
システム定義(サービスのグルーピング)
# payment-platform-system.yaml
apiVersion: backstage.io/v1alpha1
kind: System
metadata:
name: payment-platform
description: "決済プラットフォーム全体を構成するサービス群"
annotations:
backstage.io/techdocs-ref: dir:.
tags:
- payments
- core-business
spec:
owner: team-payments
domain: financial-services
---
apiVersion: backstage.io/v1alpha1
kind: Domain
metadata:
name: financial-services
description: "金融サービスドメイン"
spec:
owner: group:finance-engineering
リソース定義
# payment-database.yaml
apiVersion: backstage.io/v1alpha1
kind: Resource
metadata:
name: payment-database
description: "決済データを格納するPostgreSQLデータベース"
annotations:
backstage.io/managed-by-location: "url:https://github.com/techcorp/infrastructure/blob/main/databases/payment-db.yaml"
spec:
type: database
owner: team-platform
system: payment-platform
dependencyOf:
- component:payment-service
組織構造の定義
# org.yaml
apiVersion: backstage.io/v1alpha1
kind: Group
metadata:
name: team-payments
description: "決済チーム"
spec:
type: team
profile:
displayName: "Payments Team"
email: payments@techcorp.com
picture: https://avatars.techcorp.com/teams/payments.png
parent: engineering
children: []
members:
- user:tanaka.taro
- user:suzuki.hanako
- user:yamada.jiro
---
apiVersion: backstage.io/v1alpha1
kind: User
metadata:
name: tanaka.taro
spec:
profile:
displayName: "田中 太郎"
email: tanaka.taro@techcorp.com
picture: https://avatars.techcorp.com/users/tanaka.taro.png
memberOf:
- team-payments
Software Templates
Software Templatesは、ベストプラクティスに基づいたプロジェクトのスキャフォールディングを提供します。これにより、新しいサービスやアプリケーションを数分で立ち上げることができます。
テンプレート定義
# templates/spring-boot-service/template.yaml
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: spring-boot-service
title: "Spring Boot マイクロサービス"
description: "Spring Boot 3.x ベースのマイクロサービステンプレート。CI/CD、監視、ドキュメントが事前設定済み。"
tags:
- java
- spring-boot
- recommended
annotations:
backstage.io/techdocs-ref: dir:.
spec:
owner: team-platform
type: service
# 入力パラメータの定義
parameters:
- title: "サービス情報"
required:
- name
- description
- owner
properties:
name:
title: "サービス名"
type: string
description: "サービスの一意な名前(英数字とハイフンのみ)"
pattern: "^[a-z0-9-]+$"
ui:autofocus: true
description:
title: "説明"
type: string
description: "サービスの簡潔な説明"
owner:
title: "オーナーチーム"
type: string
description: "サービスを所有するチーム"
ui:field: OwnerPicker
ui:options:
catalogFilter:
kind: Group
- title: "技術設定"
properties:
javaVersion:
title: "Java バージョン"
type: string
enum:
- "21"
- "17"
default: "21"
database:
title: "データベース"
type: string
enum:
- postgresql
- mysql
- none
default: postgresql
messaging:
title: "メッセージング"
type: string
enum:
- kafka
- rabbitmq
- none
default: kafka
includeAuth:
title: "認証を含める"
type: boolean
default: true
- title: "リポジトリ設定"
required:
- repoUrl
properties:
repoUrl:
title: "リポジトリの場所"
type: string
ui:field: RepoUrlPicker
ui:options:
allowedHosts:
- github.com
allowedOrganizations:
- techcorp
# テンプレート実行ステップ
steps:
# 1. ファイルをスキャフォールド
- id: fetch-base
name: "テンプレートをフェッチ"
action: fetch:template
input:
url: ./skeleton
values:
name: ${{ parameters.name }}
description: ${{ parameters.description }}
owner: ${{ parameters.owner }}
javaVersion: ${{ parameters.javaVersion }}
database: ${{ parameters.database }}
messaging: ${{ parameters.messaging }}
includeAuth: ${{ parameters.includeAuth }}
# 2. catalog-info.yaml を生成
- id: catalog-info
name: "カタログ情報を生成"
action: catalog:write
input:
filePath: catalog-info.yaml
entity:
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: ${{ parameters.name }}
description: ${{ parameters.description }}
annotations:
github.com/project-slug: techcorp/${{ parameters.name }}
backstage.io/techdocs-ref: dir:.
spec:
type: service
lifecycle: experimental
owner: ${{ parameters.owner }}
# 3. GitHubリポジトリを作成
- id: publish
name: "GitHubリポジトリを作成"
action: publish:github
input:
allowedHosts:
- github.com
repoUrl: ${{ parameters.repoUrl }}
description: ${{ parameters.description }}
defaultBranch: main
protectDefaultBranch: true
repoVisibility: internal
collaborators:
- team: ${{ parameters.owner }}
access: admin
- team: platform-admins
access: admin
# 4. GitHub Actionsワークフローをセットアップ
- id: github-action
name: "CI/CDをセットアップ"
action: github:actions:dispatch
input:
repoUrl: ${{ parameters.repoUrl }}
workflowId: setup.yaml
branchOrTagName: main
# 5. カタログに登録
- id: register
name: "カタログに登録"
action: catalog:register
input:
repoContentsUrl: ${{ steps.publish.output.repoContentsUrl }}
catalogInfoPath: /catalog-info.yaml
# 出力情報
output:
links:
- title: "リポジトリ"
url: ${{ steps.publish.output.remoteUrl }}
- title: "カタログ"
url: ${{ steps.register.output.catalogInfoUrl }}
- title: "CI/CD パイプライン"
url: ${{ steps.publish.output.remoteUrl }}/actions
テンプレートのスケルトン構造
templates/spring-boot-service/
├── template.yaml
├── skeleton/
│ ├── src/
│ │ └── main/
│ │ ├── java/
│ │ │ └── com/techcorp/${{ values.name | replace('-', '') }}/
│ │ │ ├── Application.java
│ │ │ ├── config/
│ │ │ ├── controller/
│ │ │ ├── service/
│ │ │ └── repository/
│ │ └── resources/
│ │ ├── application.yaml
│ │ └── application-local.yaml
│ ├── build.gradle
│ ├── Dockerfile
│ ├── docker-compose.yaml
│ ├── .github/
│ │ └── workflows/
│ │ ├── ci.yaml
│ │ └── cd.yaml
│ ├── docs/
│ │ ├── index.md
│ │ └── architecture.md
│ ├── mkdocs.yml
│ └── README.md
└── docs/
└── index.md
TechDocs統合
TechDocsは、Docs-as-Codeアプローチでドキュメントをソースコードと一緒に管理し、自動的にBackstageポータルに公開する機能です。
TechDocsの設定
# app-config.yaml
techdocs:
builder: 'local' # または 'external' (CI/CDでビルド)
generator:
runIn: 'docker' # または 'local'
publisher:
type: 'awsS3'
awsS3:
bucketName: ${TECHDOCS_S3_BUCKET_NAME}
region: ${AWS_REGION}
credentials:
accessKeyId: ${AWS_ACCESS_KEY_ID}
secretAccessKey: ${AWS_SECRET_ACCESS_KEY}
MkDocsの設定
# mkdocs.yml(サービスリポジトリ内)
site_name: "Payment Service"
site_description: "決済サービスの技術ドキュメント"
nav:
- Home: index.md
- アーキテクチャ:
- 概要: architecture/overview.md
- データフロー: architecture/data-flow.md
- セキュリティ: architecture/security.md
- API:
- リファレンス: api/reference.md
- 認証: api/authentication.md
- エラーハンドリング: api/errors.md
- 運用:
- デプロイ: operations/deployment.md
- モニタリング: operations/monitoring.md
- トラブルシューティング: operations/troubleshooting.md
- ランブック: operations/runbook.md
- 開発ガイド:
- ローカル環境: development/local-setup.md
- テスト: development/testing.md
- コーディング規約: development/coding-standards.md
plugins:
- techdocs-core
- search
- mermaid2
markdown_extensions:
- admonition
- codehilite
- pymdownx.superfences:
custom_fences:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format
- pymdownx.tabbed:
alternate_style: true
- toc:
permalink: true
theme:
name: material
palette:
primary: indigo
accent: indigo
ADR(Architecture Decision Records)の統合
# mkdocs.yml に追記
nav:
- ADR:
- ADR-001 データベース選定: adr/001-database-selection.md
- ADR-002 認証方式: adr/002-authentication.md
- ADR-003 メッセージング: adr/003-messaging.md
<!-- docs/adr/001-database-selection.md -->
# ADR-001: データベース選定
## ステータス
承認済み
## コンテキスト
決済サービスには高い一貫性と信頼性が求められる。
## 決定
PostgreSQLを採用する。
## 理由
- ACID準拠
- 豊富なJSON機能
- 実績のある運用ノウハウ
## 影響
- RDSでのマネージドサービス利用
- バックアップ戦略の策定が必要
プラグインエコシステム
2025年現在、Backstageには200以上のプラグインが存在し、あらゆるツールとの統合が可能です。
主要プラグインカテゴリ
plugin_categories:
ci_cd:
- name: "@backstage/plugin-jenkins"
description: "Jenkinsパイプラインの表示"
- name: "@backstage/plugin-github-actions"
description: "GitHub Actionsの統合"
- name: "@roadiehq/backstage-plugin-argo-cd"
description: "ArgoCD デプロイメント管理"
- name: "@backstage/plugin-circleci"
description: "CircleCI統合"
monitoring:
- name: "@backstage/plugin-grafana"
description: "Grafanaダッシュボード埋め込み"
- name: "@backstage/plugin-prometheus"
description: "Prometheusメトリクス表示"
- name: "@backstage/plugin-datadog"
description: "Datadog統合"
- name: "@backstage/plugin-pagerduty"
description: "PagerDutyオンコール情報"
security:
- name: "@backstage/plugin-sonarqube"
description: "SonarQubeコード品質"
- name: "@backstage/plugin-snyk"
description: "Snyk脆弱性スキャン"
- name: "@roadiehq/backstage-plugin-security-insights"
description: "GitHub Security Alerts"
kubernetes:
- name: "@backstage/plugin-kubernetes"
description: "Kubernetesクラスタ管理"
- name: "@backstage/plugin-kubernetes-backend"
description: "K8sバックエンド"
cloud:
- name: "@backstage/plugin-cost-insights"
description: "クラウドコスト分析"
- name: "@backstage/plugin-aws"
description: "AWSサービス統合"
- name: "@backstage/plugin-gcp-projects"
description: "GCPプロジェクト管理"
プラグインのインストールと設定
# プラグインのインストール
yarn --cwd packages/app add @backstage/plugin-kubernetes
yarn --cwd packages/backend add @backstage/plugin-kubernetes-backend
// packages/app/src/App.tsx
import { KubernetesPage } from '@backstage/plugin-kubernetes';
const routes = (
<FlatRoutes>
{/* 他のルート */}
<Route path="/kubernetes" element={<KubernetesPage />} />
</FlatRoutes>
);
# app-config.yaml
kubernetes:
serviceLocatorMethod:
type: 'multiTenant'
clusterLocatorMethods:
- type: 'config'
clusters:
- url: ${K8S_CLUSTER_URL}
name: production
authProvider: 'serviceAccount'
serviceAccountToken: ${K8S_SA_TOKEN}
skipTLSVerify: false
skipMetricsLookup: false
カスタムプラグインの開発
// plugins/internal-tools/src/plugin.ts
import {
createPlugin,
createRoutableExtension,
} from '@backstage/core-plugin-api';
export const internalToolsPlugin = createPlugin({
id: 'internal-tools',
routes: {
root: rootRouteRef,
},
});
export const InternalToolsPage = internalToolsPlugin.provide(
createRoutableExtension({
name: 'InternalToolsPage',
component: () =>
import('./components/InternalToolsPage').then(m => m.InternalToolsPage),
mountPoint: rootRouteRef,
}),
);
// plugins/internal-tools/src/components/InternalToolsPage.tsx
import React from 'react';
import { useEntity } from '@backstage/plugin-catalog-react';
import { useApi, configApiRef } from '@backstage/core-plugin-api';
import {
Content,
ContentHeader,
Header,
HeaderLabel,
Page,
Progress,
} from '@backstage/core-components';
export const InternalToolsPage = () => {
const { entity } = useEntity();
const config = useApi(configApiRef);
return (
<Page themeId="tool">
<Header title="Internal Tools" subtitle="社内ツール統合">
<HeaderLabel label="Owner" value={entity.spec?.owner || 'Unknown'} />
</Header>
<Content>
<ContentHeader title="ツール一覧" />
{/* カスタムコンテンツ */}
</Content>
</Page>
);
};
2025年の採用状況とトレンド
採用企業の拡大
2025年、Backstageは世界中で急速に採用が進んでいます。
| 指標 | 2023年 | 2024年 | 2025年 |
|---|---|---|---|
| 公開採用企業数 | 100+ | 300+ | 700+ |
| GitHubスター数 | 22,000 | 27,000 | 32,000+ |
| 公式プラグイン数 | 100+ | 150+ | 200+ |
| コントリビューター数 | 800+ | 1,200+ | 1,800+ |
主要採用企業
- テクノロジー: Spotify, Netflix, Expedia, DoorDash, SoundCloud
- 金融: American Express, Fidelity, Capital One
- 小売: IKEA, HP, Zalando
- 通信: T-Mobile, Vodafone
- 日本企業: メルカリ, LINE, サイバーエージェント, DeNA
Platform Engineeringとの関係
flowchart TB
subgraph PE["Platform Engineering"]
IDP["Internal Developer Portal<br/>(Backstage)"]
SPC["Self-Service Platform Capabilities"]
GR["Guardrails & Governance"]
end
subgraph DevEx["Developer Experience"]
DT["Development Time ↓"]
CL["Cognitive Load ↓"]
ON["Onboarding Time ↓"]
PS["Productivity ↑"]
end
PE --> DevEx
subgraph Outcomes["ビジネス成果"]
TTM["Time to Market ↓"]
QU["品質 ↑"]
SEC["セキュリティ ↑"]
COST["コスト ↓"]
end
DevEx --> Outcomes
Gartnerの予測によると、2026年までに大企業の80%がPlatform Engineeringチームを設立し、その中核ツールとしてIDPを導入するとされています。
ベストプラクティス
段階的導入アプローチ
adoption_phases:
phase_1:
name: "基盤構築"
duration: "1-2ヶ月"
goals:
- Backstageの基本セットアップ
- 主要サービス10-20件の登録
- 基本的なTechDocs統合
success_metrics:
- カタログ登録完了率
- 基本機能の利用開始
phase_2:
name: "機能拡張"
duration: "2-3ヶ月"
goals:
- Software Templatesの整備
- CI/CDプラグイン統合
- 監視プラグイン統合
success_metrics:
- テンプレート利用率
- プラグイン活用度
phase_3:
name: "全社展開"
duration: "3-6ヶ月"
goals:
- 全サービスのカタログ登録
- カスタムプラグイン開発
- ガバナンス機能の実装
success_metrics:
- 開発者満足度
- オンボーディング時間削減
- サービス発見時間の短縮
phase_4:
name: "最適化"
duration: "継続的"
goals:
- 利用データに基づく改善
- 新機能の追加
- コミュニティへの貢献
success_metrics:
- ポータル利用率
- 開発生産性指標
カタログ品質の維持
# scorecards.yaml - サービス品質スコアカード
apiVersion: backstage.io/v1alpha1
kind: System
metadata:
name: catalog-quality-scorecard
spec:
rules:
- name: "ドキュメント完備"
description: "TechDocsが設定されている"
check:
annotation: backstage.io/techdocs-ref
weight: 20
- name: "オーナー明確"
description: "有効なオーナーチームが設定されている"
check:
spec.owner: exists
weight: 25
- name: "説明文あり"
description: "説明が50文字以上"
check:
metadata.description:
minLength: 50
weight: 15
- name: "ライフサイクル定義"
description: "ライフサイクルが明示されている"
check:
spec.lifecycle:
oneOf: [experimental, production, deprecated]
weight: 15
- name: "CI/CD連携"
description: "CI/CDパイプラインが連携されている"
check:
annotation:
oneOf:
- github.com/project-slug
- jenkins.io/job-full-name
weight: 25
まとめ
Backstageは2025年、Internal Developer Portalの事実上の標準として確固たる地位を築いています。Platform Engineeringの重要性が高まる中、開発者体験の向上とセルフサービス化を実現するBackstageの価値は、今後さらに高まることが予想されます。
導入を検討する際のポイント
- 小さく始める: 全社一斉導入ではなく、パイロットチームから開始
- 価値を可視化: 導入効果を定量的に測定・共有
- コミュニティを活用: 200以上のプラグインと活発なコミュニティを活用
- 継続的改善: 開発者フィードバックを基に継続的に改善
IDPは単なるツールではなく、開発文化の変革をもたらすプラットフォームです。Backstageを活用して、開発者が本来のソフトウェア開発に集中できる環境を構築しましょう。
参考リンク
- Backstage公式サイト
- Backstage GitHub
- CNCF Backstageプロジェクト
- Backstage Plugin Directory
- Spotify Engineering Blog - Backstage