- Published on
Platform Engineering 完全ガイド 2025: Internal Developer Platform, Backstage, Golden Path
- Authors

- Name
- Youngju Kim
- @fjvbn20031
目次(もくじ)
1. Platform Engineeringとは?
1.1 DevOpsの進化(しんか)とPlatform Engineering
DevOpsは開発(かいはつ)と運用(うんよう)の壁(かべ)を取(と)り払(はら)いましたが、新(あたら)しい問題(もんだい)を生(う)みました。「You build it, you run it」の原則(げんそく)が広(ひろ)まるにつれ、開発者の**認知負荷(にんちふか)(Cognitive Load)**が急激(きゅうげき)に増加(ぞうか)しました。
開発者の認知負荷の変化:
2010年代前半: 現在:
┌───────────────┐ ┌───────────────┐
│ ビジネスロジック │ │ ビジネスロジック │
│ │ ├───────────────┤
│ │ │ CI/CDパイプライン│
│ │ ├───────────────┤
│ │ │ インフラ管理 │
│ │ ├───────────────┤
│ │ │ 可観測性 │
│ │ ├───────────────┤
│ │ │ セキュリティ │
│ │ ├───────────────┤
│ │ │ Kubernetes │
└───────────────┘ └───────────────┘
Gartnerは2026年までに大規模(だいきぼ)ソフトウェアエンジニアリング組織(そしき)の**80%**がPlatform Engineeringチームを設立(せつりつ)すると予測(よそく)しました。
1.2 Platform Engineeringの定義(ていぎ)
Platform Engineeringは、セルフサービス機能(きのう)を備(そな)えた**Internal Developer Platform(IDP)**を設計(せっけい)し構築(こうちく)する分野(ぶんや)です。開発者がインフラの複雑性(ふくざつせい)に直接(ちょくせつ)向(む)き合(あ)わずに、必要なリソースをプロビジョニングし、アプリケーションをデプロイできるようにします。
核心的目標(もくひょう):
- 開発者の認知負荷の軽減(けいげん): インフラの複雑性を抽象化(ちゅうしょうか)
- セルフサービス: チケットなしで開発者が直接リソースプロビジョニング
- 標準化(ひょうじゅんか): Golden Pathによるベストプラクティスの提供(ていきょう)
- ガードレール: セキュリティとコンプライアンスを自動的(じどうてき)に保証(ほしょう)
- Developer Experience(DX)の向上(こうじょう): 開発者の生産性(せいさんせい)と満足度(まんぞくど)の向上
1.3 Platform Team vs DevOps Team
# Team Topologiesベースの比較
devops_team:
役割: "開発と運用の橋渡し"
アプローチ: "各チームにDevOpsエンジニアを派遣"
問題点:
- "DevOpsエンジニアがボトルネックに"
- "チームごとに異なるツールとプロセス"
- "知識が個人に偏る"
- "反復的なインフラ作業"
platform_team:
役割: "内部プラットフォームプロダクトの開発と運用"
アプローチ: "セルフサービスプラットフォームの提供"
利点:
- "開発者の自律性向上"
- "標準化されたツールとプロセス"
- "知識がプラットフォームに内在化"
- "自動化されたガードレール"
team_topologies:
stream_aligned: "ビジネス機能開発チーム(開発者)"
platform: "IDPを構築・運用するチーム"
enabling: "新技術導入を支援するチーム"
complicated_subsystem: "複雑なサブシステムの専門家チーム"
2. IDP(Internal Developer Platform)アーキテクチャ
2.1 IDPの5層(そう)構造(こうぞう)
┌─────────────────────────────────────────────────────┐
│ Developer Portal Layer │
│ (Backstage, Port, Humanitec Score UI) │
├─────────────────────────────────────────────────────┤
│ Integration & Delivery Layer │
│ (CI/CD: GitHub Actions, ArgoCD, Tekton) │
├─────────────────────────────────────────────────────┤
│ Security & Compliance Layer │
│ (OPA, Kyverno, Vault, Policy-as-Code) │
├─────────────────────────────────────────────────────┤
│ Resource Management Layer │
│ (Terraform, Crossplane, Pulumi, Helm) │
├─────────────────────────────────────────────────────┤
│ Infrastructure Layer │
│ (AWS, GCP, Azure, Kubernetes) │
└─────────────────────────────────────────────────────┘
2.2 IDP核心(かくしん)コンポーネント
# IDP核心コンポーネント
service_catalog:
説明: "すべてのサービス、API、インフラの中央カタログ"
機能:
- "サービスオーナーと依存関係の追跡"
- "APIドキュメントの自動生成"
- "サービス成熟度スコアカード"
ツール: "Backstage Software Catalog, Port"
software_templates:
説明: "新プロジェクトを標準化された方法で作成"
機能:
- "マイクロサービスのスキャフォールディング"
- "CI/CDパイプラインの自動設定"
- "モニタリング/ロギングをデフォルト包含"
ツール: "Backstage Software Templates, Cookiecutter"
self_service_infrastructure:
説明: "開発者が直接インフラをプロビジョニング"
機能:
- "データベース作成"
- "キャッシュクラスタのプロビジョニング"
- "メッセージキューの設定"
ツール: "Crossplane, Terraform modules, Pulumi"
documentation:
説明: "コードリポジトリと連携した技術ドキュメント"
機能:
- "Markdownベースのドキュメント"
- "APIドキュメント自動化"
- "アーキテクチャダイアグラム"
ツール: "Backstage TechDocs, ReadTheDocs"
3. Backstage深層(しんそう)分析
3.1 Backstageとは?
BackstageはSpotifyが作成(さくせい)しCNCFに寄贈(きぞう)したオープンソースの開発者ポータルフレームワークです。2020年にオープンソース化され、現在(げんざい)CNCF Incubatingプロジェクトです。
3.2 Software Catalog
Software CatalogはBackstageの核心で、組織のすべてのソフトウェア資産(しさん)を追跡(ついせき)します。
# catalog-info.yaml - サービス登録ファイル
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: user-service
description: "ユーザー管理マイクロサービス"
annotations:
github.com/project-slug: "myorg/user-service"
backstage.io/techdocs-ref: "dir:."
pagerduty.com/service-id: "PXXXXXX"
grafana/dashboard-selector: "user-service"
sonarqube.org/project-key: "myorg_user-service"
tags:
- java
- spring-boot
- user-management
links:
- url: "https://grafana.internal/d/user-service"
title: "Grafana Dashboard"
icon: dashboard
- url: "https://user-service.internal/swagger-ui"
title: "API Docs"
icon: docs
spec:
type: service
lifecycle: production
owner: team-backend
system: user-platform
providesApis:
- user-api
consumesApis:
- auth-api
- notification-api
dependsOn:
- resource:default/user-database
- resource:default/redis-cache
---
apiVersion: backstage.io/v1alpha1
kind: API
metadata:
name: user-api
description: "ユーザー管理REST API"
spec:
type: openapi
lifecycle: production
owner: team-backend
system: user-platform
definition:
$text: ./api/openapi.yaml
---
apiVersion: backstage.io/v1alpha1
kind: Resource
metadata:
name: user-database
description: "ユーザーサービスPostgreSQLデータベース"
spec:
type: database
owner: team-backend
system: user-platform
3.3 Software Templates
# template.yaml - マイクロサービス作成テンプレート
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: spring-boot-microservice
title: "Spring Boot Microservice"
description: "標準Spring Bootマイクロサービスプロジェクトの作成"
tags:
- java
- spring-boot
- recommended
spec:
owner: team-platform
type: service
parameters:
- title: "サービス基本情報"
required:
- serviceName
- owner
- description
properties:
serviceName:
title: "サービス名"
type: string
description: "kebab-case形式(例: user-service)"
pattern: "^[a-z][a-z0-9-]*$"
owner:
title: "所有チーム"
type: string
ui:field: OwnerPicker
ui:options:
allowedKinds:
- Group
description:
title: "サービス説明"
type: string
javaVersion:
title: "Javaバージョン"
type: string
enum: ["17", "21"]
default: "21"
- title: "インフラ設定"
properties:
database:
title: "データベース"
type: string
enum: ["postgresql", "mysql", "none"]
default: "postgresql"
cache:
title: "キャッシュ"
type: string
enum: ["redis", "none"]
default: "redis"
steps:
- id: fetch-template
name: "テンプレートコードの取得"
action: fetch:template
input:
url: "./skeleton"
values:
serviceName: "${{ parameters.serviceName }}"
owner: "${{ parameters.owner }}"
description: "${{ parameters.description }}"
javaVersion: "${{ parameters.javaVersion }}"
database: "${{ parameters.database }}"
cache: "${{ parameters.cache }}"
- id: publish
name: "GitHubリポジトリの作成"
action: publish:github
input:
allowedHosts: ["github.com"]
repoUrl: "github.com?owner=myorg&repo=${{ parameters.serviceName }}"
description: "${{ parameters.description }}"
defaultBranch: main
protectDefaultBranch: true
repoVisibility: internal
- id: register
name: "Backstageカタログに登録"
action: catalog:register
input:
repoContentsUrl: "${{ steps.publish.output.repoContentsUrl }}"
catalogInfoPath: "/catalog-info.yaml"
- id: create-argocd-app
name: "ArgoCDアプリケーションの作成"
action: argocd:create-resources
input:
appName: "${{ parameters.serviceName }}"
argoInstance: "main"
namespace: "${{ parameters.serviceName }}"
repoUrl: "${{ steps.publish.output.remoteUrl }}"
path: "k8s/overlays/development"
output:
links:
- title: "GitHubリポジトリ"
url: "${{ steps.publish.output.remoteUrl }}"
- title: "Backstageカタログ"
icon: catalog
entityRef: "${{ steps.register.output.entityRef }}"
3.4 TechDocs
# mkdocs.yml - TechDocs設定
site_name: "User Service"
site_description: "ユーザー管理マイクロサービス技術ドキュメント"
nav:
- Home: index.md
- Architecture:
- Overview: architecture/overview.md
- Data Model: architecture/data-model.md
- API Design: architecture/api-design.md
- Development:
- Getting Started: development/getting-started.md
- Local Setup: development/local-setup.md
- Testing Guide: development/testing.md
- Operations:
- Deployment: operations/deployment.md
- Monitoring: operations/monitoring.md
- Runbook: operations/runbook.md
plugins:
- techdocs-core
3.5 Backstageプラグインエコシステム
# 人気Backstageプラグイン
kubernetes_plugin:
機能: "K8sクラスタのサービス状態確認"
活用: "Pod状態、ログ、イベントをBackstageで直接確認"
github_actions_plugin:
機能: "CI/CDパイプライン状態の表示"
活用: "ビルド/デプロイ状況をサービスページで確認"
pagerduty_plugin:
機能: "オンコールスケジュールとインシデント連携"
活用: "サービスオーナーのオンコール状態を表示"
cost_insights_plugin:
機能: "クラウドコスト分析"
活用: "サービス別コスト追跡とトレンド分析"
tech_radar_plugin:
機能: "テクノロジーレーダーの可視化"
活用: "組織の技術採用状況の管理"
sonarqube_plugin:
機能: "コード品質メトリクスの表示"
活用: "サービス別コード品質スコアの確認"
4. Golden Path設計(せっけい)
4.1 Golden Pathとは?
Golden Path(ゴールデンロードまたはPaved Roadとも呼(よ)ばれる)は、組織が推奨(すいしょう)する標準化された開発パスです。開発者が新(あたら)しいサービスを作る際(さい)に「どの言語(げんご)を使(つか)うか、CI/CDはどう設定するか、モニタリングは何を使うか」と悩(なや)まずに済(す)むよう、整備(せいび)された道(みち)を提供します。
Golden Pathの核心原則:
1. 提案であって強制ではない (Suggestion, not Mandate)
├── 強制しないが従えば最も楽な道
├── 外れることもできるが、外れるとサポートは自己責任
└── 「未舗装道路も行けるが、舗装道路の方が速い」
2. Day 1からプロダクションレディ
├── CI/CDパイプラインがデフォルト含有
├── モニタリング/ロギング/アラートの基本設定
├── セキュリティスキャンの自動化
└── ヘルスチェックエンドポイント
3. 継続的な進化
├── 開発者フィードバックの反映
├── 新技術/ツールの統合
└── 定期的なアップデート
4.2 Golden Path例(れい): 新マイクロサービス
# Golden Path: スキャフォールディングからプロダクションデプロイまで
golden_path_microservice:
step_1_scaffolding:
ツール: "Backstage Software Template"
結果:
- "GitHubリポジトリ作成"
- "プロジェクト構造(src, tests, k8s, docs)"
- "Dockerfile, docker-compose.yml"
- "CI/CDパイプライン(.github/workflows)"
- "catalog-info.yaml(Backstage登録)"
- "mkdocs.yml(TechDocs)"
step_2_development:
ツール: "標準開発環境"
結果:
- "devcontainer設定"
- "pre-commit hooks(lint, format, security)"
- "統合テストフレームワーク"
- "ローカル開発環境(docker-compose)"
step_3_ci_cd:
ツール: "GitHub Actions + ArgoCD"
結果:
- "PR時: ビルド、テスト、セキュリティスキャン、コードレビュー"
- "マージ時: Dockerイメージビルド、レジストリプッシュ"
- "ArgoCD自動同期(dev -> staging -> prod)"
step_4_observability:
ツール: "OpenTelemetry + Grafana Stack"
結果:
- "メトリクス: Prometheus + Grafana"
- "ログ: Loki + Grafana"
- "トレーシング: Tempo + Grafana"
- "アラート: Grafana Alerting -> Slack/PagerDuty"
step_5_security:
ツール: "自動化されたセキュリティガードレール"
結果:
- "SAST: SonarQube"
- "SCA: Dependabot, Snyk"
- "イメージスキャン: Trivy"
- "Policy-as-Code: OPA/Kyverno"
4.3 標準CI/CDパイプライン
# .github/workflows/golden-path-ci.yml
name: Golden Path CI
on:
pull_request:
branches: [main]
push:
branches: [main]
env:
REGISTRY: ghcr.io
IMAGE_NAME: "${{ github.repository }}"
jobs:
lint-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '21'
cache: 'gradle'
- name: Lint
run: ./gradlew spotlessCheck
- name: Unit Tests
run: ./gradlew test
- name: Integration Tests
run: ./gradlew integrationTest
security-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: SonarQube Scan
uses: SonarSource/sonarqube-scan-action@v2
env:
SONAR_TOKEN: "${{ secrets.SONAR_TOKEN }}"
build-and-push:
needs: [lint-and-test, security-scan]
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: "${{ env.REGISTRY }}"
username: "${{ github.actor }}"
password: "${{ secrets.GITHUB_TOKEN }}"
- name: Build and Push
uses: docker/build-push-action@v5
with:
push: true
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
- name: Scan Image
uses: aquasecurity/trivy-action@master
with:
image-ref: "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}"
format: 'table'
exit-code: '1'
severity: 'CRITICAL,HIGH'
5. セルフサービスインフラ
5.1 Crossplaneによるインフラプロビジョニング
CrossplaneはKubernetes APIを拡張(かくちょう)して、クラウドリソースをK8sマニフェストで管理(かんり)できるようにします。
# Crossplane Composition: RDS PostgreSQL
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: postgresql-aws
labels:
provider: aws
database: postgresql
spec:
compositeTypeRef:
apiVersion: database.platform.io/v1alpha1
kind: PostgreSQLInstance
resources:
- name: rds-instance
base:
apiVersion: rds.aws.crossplane.io/v1alpha1
kind: DBInstance
spec:
forProvider:
engine: postgres
engineVersion: "15"
dbInstanceClass: db.t3.medium
allocatedStorage: 20
masterUsername: admin
skipFinalSnapshot: true
publiclyAccessible: false
providerConfigRef:
name: aws-provider
patches:
- fromFieldPath: "spec.parameters.storageGB"
toFieldPath: "spec.forProvider.allocatedStorage"
- fromFieldPath: "spec.parameters.instanceClass"
toFieldPath: "spec.forProvider.dbInstanceClass"
---
# 開発者が要求するリソース(Claim)
apiVersion: database.platform.io/v1alpha1
kind: PostgreSQLInstance
metadata:
name: user-db
namespace: backend
spec:
parameters:
storageGB: 50
instanceClass: db.t3.medium
compositionSelector:
matchLabels:
provider: aws
database: postgresql
5.2 Terraformモジュールベースのセルフサービス
# modules/microservice-infra/main.tf
# マイクロサービスインフラ標準モジュール
variable "service_name" {
type = string
description = "マイクロサービス名"
}
variable "team" {
type = string
description = "所有チーム"
}
variable "environment" {
type = string
description = "環境(dev, staging, prod)"
}
variable "enable_database" {
type = bool
default = false
}
variable "enable_cache" {
type = bool
default = false
}
# EKS Namespace
resource "kubernetes_namespace" "service" {
metadata {
name = var.service_name
labels = {
team = var.team
environment = var.environment
managed-by = "terraform"
}
}
}
# PostgreSQL(オプション)
module "database" {
count = var.enable_database ? 1 : 0
source = "../rds-postgresql"
name = "${var.service_name}-db"
environment = var.environment
instance_class = var.environment == "prod" ? "db.r6g.large" : "db.t3.medium"
allocated_storage = var.environment == "prod" ? 100 : 20
multi_az = var.environment == "prod" ? true : false
}
# Redis Cache(オプション)
module "cache" {
count = var.enable_cache ? 1 : 0
source = "../elasticache-redis"
name = "${var.service_name}-cache"
environment = var.environment
node_type = var.environment == "prod" ? "cache.r6g.large" : "cache.t3.medium"
num_cache_nodes = var.environment == "prod" ? 3 : 1
}
# モニタリングダッシュボード自動生成
module "monitoring" {
source = "../grafana-dashboard"
service_name = var.service_name
namespace = kubernetes_namespace.service.metadata[0].name
enable_database_metrics = var.enable_database
enable_cache_metrics = var.enable_cache
}
output "namespace" {
value = kubernetes_namespace.service.metadata[0].name
}
output "database_endpoint" {
value = var.enable_database ? module.database[0].endpoint : null
sensitive = true
}
6. Developer Experience測定(そくてい)
6.1 DORAメトリクス
# DORAメトリクス(DevOps Research and Assessment)
dora_metrics:
deployment_frequency:
説明: "デプロイ頻度 - プロダクションにどれだけ頻繁にデプロイするか"
elite: "1日に複数回"
high: "週1回〜日1回"
medium: "月1回〜週1回"
low: "月1回未満"
lead_time_for_changes:
説明: "変更リードタイム - コミットからプロダクションデプロイまでの時間"
elite: "1時間未満"
high: "1日〜1週間"
medium: "1週間〜1ヶ月"
low: "1ヶ月以上"
change_failure_rate:
説明: "変更失敗率 - デプロイ後の障害/ロールバック率"
elite: "0-15%"
high: "16-30%"
medium: "16-30%"
low: "31%以上"
time_to_restore:
説明: "復旧時間 - 障害発生からサービス復旧までの時間"
elite: "1時間未満"
high: "1日未満"
medium: "1日〜1週間"
low: "1週間以上"
6.2 SPACEフレームワーク
# SPACEフレームワーク
space_framework:
S_satisfaction:
説明: "開発者の満足度とウェルビーイング"
測定:
- "四半期ごとの開発者満足度アンケート(NPS)"
- "バーンアウトリスク評価"
- "ツール/プラットフォーム満足度スコア"
P_performance:
説明: "コードとシステムのパフォーマンス"
測定:
- "コードレビュー品質スコア"
- "サービス信頼性(SLO達成率)"
- "顧客影響インシデント数"
A_activity:
説明: "開発活動の定量的測定"
測定:
- "PR数とサイズ"
- "デプロイ頻度"
- "コードレビュー参加度"
注意: "活動量だけで生産性を判断しないこと"
C_communication:
説明: "チーム間コラボレーションの効果性"
測定:
- "PRレビュー応答時間"
- "ドキュメント最新化率"
- "クロスチームコラボレーション頻度"
E_efficiency:
説明: "開発プロセスの効率性"
測定:
- "ビルド時間"
- "テスト実行時間"
- "環境プロビジョニング時間"
- "オンボーディング時間(最初のPRまで)"
6.3 Platform効果(こうか)測定ダッシュボード
# Platform効果測定スクリプト
# platform_metrics.py
import statistics
def calculate_platform_metrics(data):
"""プラットフォーム効果の核心指標を計算"""
metrics = {}
# 1. サービス作成時間
creation_times = data.get('service_creation_times', [])
if creation_times:
metrics['avg_service_creation_minutes'] = round(
statistics.mean(creation_times), 1
)
metrics['target_service_creation'] = 15 # 目標: 15分
# 2. オンボーディング時間(最初のコミットまで)
onboarding_hours = data.get('onboarding_hours', [])
if onboarding_hours:
metrics['avg_onboarding_hours'] = round(
statistics.mean(onboarding_hours), 1
)
metrics['target_onboarding_hours'] = 4 # 目標: 4時間
# 3. セルフサービス率
total_requests = data.get('total_infra_requests', 0)
self_service = data.get('self_service_requests', 0)
if total_requests > 0:
metrics['self_service_rate'] = round(
(self_service / total_requests) * 100, 1
)
metrics['target_self_service_rate'] = 80 # 目標: 80%
# 4. Golden Path採用率
total_svc = data.get('total_services', 0)
gp_svc = data.get('golden_path_services', 0)
if total_svc > 0:
metrics['golden_path_adoption_rate'] = round(
(gp_svc / total_svc) * 100, 1
)
# 5. プラットフォームNPS
nps_scores = data.get('nps_scores', [])
if nps_scores:
promoters = len([s for s in nps_scores if s >= 9])
detractors = len([s for s in nps_scores if s <= 6])
total = len(nps_scores)
metrics['platform_nps'] = round(
((promoters - detractors) / total) * 100
)
return metrics
7. Platform as a Product
7.1 プロダクト管理原則の適用(てきよう)
# Platform as a Productの原則
principles:
developer_is_customer:
説明: "開発者がプラットフォームの顧客"
実践:
- "定期的なユーザーインタビュー"
- "NPS測定"
- "ユーザビリティテスト"
- "フィードバックループ"
product_roadmap:
説明: "プラットフォームにもプロダクトロードマップが必要"
実践:
- "四半期ごとのロードマップ共有"
- "優先度ベースの機能開発"
- "リリースノートの公開"
- "変更事項の通知"
sla_and_support:
説明: "内部SLAとサポート体制"
実践:
- "プラットフォーム可用性SLA(例: 99.9%)"
- "応答時間SLA(例: 30分)"
- "専用サポートチャンネル(Slack)"
- "定期的なオフィスアワー"
marketing:
説明: "内部マーケティングで採用を促進"
実践:
- "ショーケースセッション"
- "ユースケースの共有"
- "チャンピオンプログラム"
- "内部ブログ/ニュースレター"
8. IDPツール比較
┌──────────────┬──────────────┬──────────────┬──────────────┬──────────────┐
│ │ Backstage │ Port │ Humanitec │ Kratix │
├──────────────┼──────────────┼──────────────┼──────────────┼──────────────┤
│ 種類 │ オープンソース│ SaaS/セルフ │ SaaS │ オープンソース│
│ 開発元 │ Spotify/CNCF │ Port │ Humanitec │ Syntasso │
│ 核心強み │ 拡張性 │ 高速セット │ スコアエンジン│ K8sネイティブ│
│ プラグイン │ 100+ │ 内蔵 │ 内蔵 │ K8s CRD │
│ セルフサービス│ テンプレート │ アクション │ スコアベース │ Promiseベース│
│ 学習曲線 │ 高い │ 中程度 │ 低い │ 高い │
│ カスタマイズ │ 非常に高い │ 高い │ 中程度 │ 高い │
│ コミュニティ │ 非常に活発 │ 成長中 │ 小規模 │ 成長中 │
│ 適正規模 │ 50+エンジニア│ 20+エンジニア│ 20+エンジニア│ K8s専門チーム│
└──────────────┴──────────────┴──────────────┴──────────────┴──────────────┘
9. GitOpsとPlatform Engineering
9.1 ArgoCD + Backstage統合
# ArgoCDアプリケーション定義
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: user-service
namespace: argocd
labels:
team: backend
managed-by: backstage
spec:
project: default
source:
repoURL: "https://github.com/myorg/user-service"
targetRevision: HEAD
path: k8s/overlays/production
destination:
server: "https://kubernetes.default.svc"
namespace: user-service
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
9.2 ApplicationSetでマルチ環境(かんきょう)管理
# ArgoCD ApplicationSet - 環境別自動デプロイ
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: user-service-environments
namespace: argocd
spec:
generators:
- list:
elements:
- environment: development
cluster: dev-cluster
namespace: user-service-dev
- environment: staging
cluster: staging-cluster
namespace: user-service-staging
- environment: production
cluster: prod-cluster
namespace: user-service-prod
template:
metadata:
name: "user-service-{{ environment }}"
spec:
project: default
source:
repoURL: "https://github.com/myorg/user-service"
targetRevision: HEAD
path: "k8s/overlays/{{ environment }}"
destination:
server: "https://{{ cluster }}.internal:6443"
namespace: "{{ namespace }}"
syncPolicy:
automated:
prune: true
selfHeal: true
10. セキュリティガードレール
10.1 Policy-as-Code: OPA/Gatekeeper
# Gatekeeper ConstraintTemplate: 必須ラベル検証
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: requiredlabels
spec:
crd:
spec:
names:
kind: RequiredLabels
validation:
openAPIV3Schema:
type: object
properties:
labels:
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package requiredlabels
violation[{"msg": msg}] {
provided := {label | input.review.object.metadata.labels[label]}
required := {label | label := input.parameters.labels[_]}
missing := required - provided
count(missing) > 0
msg := sprintf("Missing required labels: %v", [missing])
}
---
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: RequiredLabels
metadata:
name: require-team-label
spec:
match:
kinds:
- apiGroups: ["apps"]
kinds: ["Deployment"]
parameters:
labels:
- "team"
- "environment"
- "service"
10.2 Kyvernoポリシー
# Kyvernoポリシー: イメージレジストリ制限
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrict-image-registries
spec:
validationFailureAction: Enforce
rules:
- name: validate-image-registry
match:
any:
- resources:
kinds:
- Pod
validate:
message: "承認されたレジストリのイメージのみ使用できます。"
pattern:
spec:
containers:
- image: "ghcr.io/myorg/* | 123456789.dkr.ecr.*.amazonaws.com/*"
---
# Kyvernoポリシー: リソースリミット必須
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-resource-limits
spec:
validationFailureAction: Enforce
rules:
- name: validate-resources
match:
any:
- resources:
kinds:
- Pod
validate:
message: "すべてのコンテナにCPU/メモリのrequestsとlimitsを設定する必要があります。"
pattern:
spec:
containers:
- resources:
requests:
memory: "?*"
cpu: "?*"
limits:
memory: "?*"
cpu: "?*"
11. 組織(そしき)規模別(きぼべつ)IDP導入(どうにゅう)戦略
# 組織規模別IDP導入戦略
small_org: # 20-50エンジニア
phase_1:
- "標準CI/CDパイプラインの構築"
- "サービスカタログ(シンプルなWikiまたはスプレッドシート)"
- "Terraformモジュールの標準化"
phase_2:
- "Backstage導入(Software Catalog)"
- "1-2個のGolden Pathテンプレート"
- "基本セルフサービス(DB、キャッシュ)"
導入期間: "3〜6ヶ月"
medium_org: # 50-200エンジニア
phase_1:
- "Backstageフルスタック導入"
- "3-5個のGolden Pathテンプレート"
- "CrossplaneまたはTerraformベースのセルフサービス"
- "DORAメトリクス測定"
phase_2:
- "セキュリティガードレール(OPA/Kyverno)"
- "コスト可視性統合"
- "開発者満足度アンケート"
導入期間: "6〜12ヶ月"
large_org: # 200+エンジニア
phase_1:
- "専任プラットフォームチーム編成(8-15名)"
- "Platform as a Product運用モデル"
- "包括的IDPアーキテクチャ設計"
phase_2:
- "マルチクラスタ/マルチクラウドサポート"
- "高度なセキュリティ・コンプライアンス自動化"
- "FinOps統合"
導入期間: "12〜18ヶ月"
12. クイズ
Q1. Platform EngineeringがDevOpsと異なる点を3つ説明してください。
回答(かいとう):
-
アプローチ: DevOpsは各チームにDevOpsエンジニアを派遣(はけん)してサポートしますが、Platform Engineeringはセルフサービスプラットフォームを構築して開発者が直接インフラを管理できるようにします。
-
スケーラビリティ: DevOpsエンジニアは個人の能力に依存するため、組織が大きくなるとボトルネックになりますが、Platform Engineeringはプラットフォーム自体がスケール可能で、開発者数の増加に比例して拡張されます。
-
標準化: DevOpsではチームごとに異なるツールとプロセスを使用できますが、Platform EngineeringはGolden Pathを通じて組織全体の標準化された開発パスを提供します。知識が個人ではなくプラットフォームに内在化されます。
Q2. Backstageの核心コンポーネント3つとそれぞれの役割を説明してください。
回答:
-
Software Catalog: 組織のすべてのソフトウェア資産(サービス、API、ライブラリ、インフラ)を追跡する中央カタログ。サービスオーナー、依存関係、ステータスを一目で把握できます。
-
Software Templates: 新プロジェクトを標準化された方法で作成するテンプレートシステム。GitHubリポジトリ作成、CI/CD設定、Backstage登録まで自動化します。
-
TechDocs: docs-as-code方式の技術ドキュメントシステム。コードリポジトリ内のMarkdownファイルをBackstageでレンダリングし、サービス別技術ドキュメントを中央で閲覧(えつらん)できます。
Q3. Golden Pathの核心原則3つを説明し、「強制標準」との違いを説明してください。
回答:
核心原則:
-
提案であって強制ではない: Golden Pathに従(したが)えば最も楽な道ですが、外(はず)れる自由があります。ただし、外れるとプラットフォームチームのサポートは受(う)けられません。
-
Day 1からプロダクションレディ: Golden Pathで作成されたサービスはCI/CD、モニタリング、セキュリティスキャンがデフォルトで含まれ、Day 1からプロダクションデプロイが可能です。
-
継続的進化: 固定(こてい)された標準ではなく、開発者フィードバックと技術の発展に応(おう)じて継続的にアップデートされます。
強制標準との違い: 強制標準は違反時にブロックまたは罰則(ばっそく)がありますが、Golden Pathは従えばリワード(簡単なインフラ、自動モニタリング、迅速なサポート)があるインセンティブベースのアプローチです。
Q4. DORAメトリクスの4つの指標とそれぞれの「Elite」レベルを説明してください。
回答:
-
デプロイ頻度(Deployment Frequency): プロダクションにどれだけ頻繁にデプロイするか。Elite: 1日に複数回(オンデマンドデプロイ)。
-
変更リードタイム(Lead Time for Changes): コードコミットからプロダクションデプロイまでの時間。Elite: 1時間未満。
-
変更失敗率(Change Failure Rate): デプロイ後のロールバック、ホットフィックス、障害の割合。Elite: 0-15%。
-
サービス復旧時間(Time to Restore Service): 障害発生からサービス復旧までの時間。Elite: 1時間未満。
Q5. Platform as a Productの原則で「開発者が顧客」という概念を実践するための方法4つを説明してください。
回答:
-
定期的なユーザーインタビュー: 開発者と1対1またはグループインタビューを実施し、ペインポイントと要件を把握します。実際の使用パターンを観察するユーザビリティテストも含みます。
-
NPS(Net Promoter Score)測定: 四半期ごとにプラットフォーム満足度アンケートを実施し、定量的に開発者体験を追跡します。トレンドの変化をモニタリングし改善領域を特定します。
-
プロダクトロードマップとリリースノート: プラットフォームの今後の計画を透明に共有し、変更事項をリリースノートとして整理して開発者が新機能を活用できるようにします。
-
専用サポートチャンネルとSLA: Slackチャンネル、オフィスアワーなど専用サポートチャンネルを運営し、応答時間SLAを設定して開発者が安定的にプラットフォームを利用できるようにします。
13. 参考資料(さんこうしりょう)
- Backstage.io - https://backstage.io/
- CNCF Platforms White Paper - CNCF TAG App Delivery
- Team Topologies - Matthew Skelton & Manuel Pais
- Platform Engineering on Kubernetes - Manning Publications
- DORAメトリクス - https://dora.dev/
- SPACEフレームワーク - Microsoft Research
- Crossplane Documentation - https://crossplane.io/
- ArgoCD Documentation - https://argo-cd.readthedocs.io/
- Port - https://www.getport.io/
- Humanitec - https://humanitec.com/
- Kratix - https://kratix.io/
- OPA Gatekeeper - https://open-policy-agent.github.io/gatekeeper/
- Kyverno - https://kyverno.io/
- Spotify Engineering Blog - Platform Engineering記事
まとめ
Platform EngineeringはDevOpsの自然(しぜん)な進化(しんか)です。開発者の認知負荷を軽減(けいげん)し、セルフサービスを通(つう)じて生産性(せいさんせい)を高(たか)め、Golden Pathで組織全体の品質(ひんしつ)と一貫性(いっかんせい)を向上させます。
成功(せいこう)するPlatform Engineeringの核心は**「プロダクトのようにプラットフォームを運営すること」**です。開発者を顧客(こきゃく)として扱(あつか)い、フィードバックを収集(しゅうしゅう)し、継続的(けいぞくてき)に改善(かいぜん)しましょう。最高のプラットフォームは、開発者が自然(しぜん)に使(つか)いたくなるプラットフォームです。