- Authors

- Name
- Youngju Kim
- @fjvbn20031
- はじめに
- 1. デプロイ戦略(せんりゃく)
- 2. GitOps
- 3. モノレポCI
- 4. Feature Flags(フィーチャーフラグ)
- 5. 環境管理(かんきょうかんり)
- 6. パイプラインセキュリティ
- 7. ロールバック戦略(せんりゃく)
- 8. パイプラインパフォーマンス最適化(さいてきか)
- 9. リリース管理(かんり)
- 10. マルチクラウドデプロイ
- 11. 実践(じっせん)クイズ
- 12. CI/CD成熟度(せいじゅくど)チェックリスト
- 13. 参考資料(さんこうしりょう)
はじめに
2024年(ねん)のDORA(DevOps Research and Assessment)レポートによると、エリートチームは1日(いちにち)に複数回(ふくすうかい)デプロイし、変更失敗率(へんこうしっぱいりつ)は5%未満(みまん)です。一方(いっぽう)、低(てい)パフォーマンスチームは月(つき)1回(いっかい)のデプロイで、復旧(ふっきゅう)に数週間(すうしゅうかん)かかります。この格差(かくさ)の核心(かくしん)は、CI/CDパイプラインの成熟度(せいじゅくど)にあります。
単純(たんじゅん)なビルド・テスト・デプロイを超(こ)えて、現代的(げんだいてき)なCI/CDはデプロイ戦略(せんりゃく)(Blue-Green、Canary)、GitOps、モノレポ最適化(さいてきか)、フィーチャーフラグ、セキュリティパイプラインまでカバーします。このガイドは2025年(ねん)現在(げんざい)、プロダクション環境(かんきょう)で検証(けんしょう)された上級(じょうきゅう)CI/CD戦略を体系的(たいけいてき)にまとめます。
1. デプロイ戦略(せんりゃく)
1.1 ローリングアップデート
最(もっと)も基本的(きほんてき)なデプロイ方式(ほうしき)で、インスタンスを順次(じゅんじ)入(い)れ替(か)えます。
時間 ->
インスタンス 1: [v1] [v1] [v2] [v2] [v2]
インスタンス 2: [v1] [v1] [v1] [v2] [v2]
インスタンス 3: [v1] [v1] [v1] [v1] [v2]
トラフィック: 100% v1 -> 混合 -> 100% v2
# Kubernetes Rolling Update
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-server
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 最大1つの追加Pod
maxUnavailable: 0 # ダウンタイムゼロ
template:
spec:
containers:
- name: api
image: myapp:v2
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
メリット: シンプル、追加(ついか)リソース最小(さいしょう)、段階的(だんかいてき)な入替(いれかえ) デメリット: デプロイ中(ちゅう)のv1/v2混合(こんごう)トラフィック、即座(そくざ)のロールバックが困難(こんなん)
1.2 Blue-Greenデプロイ
2つの同一(どういつ)環境(かんきょう)(Blue/Green)を維持(いじ)し、トラフィックを一度(いちど)に切(き)り替(か)えます。
┌─────────────────────────────────────────────┐
│ │
│ Load Balancer │
│ | │
│ v (切替前: Blueへトラフィック) │
│ ┌───────────┐ ┌───────────┐ │
│ │ Blue │ │ Green │ │
│ │ (v1) │ │ (v2) │ │
│ │ Active │ │ Standby │ │
│ └───────────┘ └───────────┘ │
│ │
│ 切替後: Greenへ100%トラフィック切替 │
│ │
│ ┌───────────┐ ┌───────────┐ │
│ │ Blue │ │ Green │ │
│ │ (v1) │ │ (v2) │ │
│ │ Standby │ │ Active │ │
│ └───────────┘ └───────────┘ │
└─────────────────────────────────────────────┘
# AWS ALBを使ったBlue-Green (GitHub Actions)
name: Blue-Green Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build and Push Docker Image
run: |
docker build -t myapp:${{ github.sha }} .
docker push myregistry/myapp:${{ github.sha }}
- name: Deploy to Green Environment
run: |
aws ecs update-service \
--cluster production \
--service green-service \
--task-definition myapp:${{ github.sha }}
- name: Run Smoke Tests on Green
run: |
./scripts/smoke-test.sh https://green.myapp.com
- name: Switch Traffic to Green
run: |
aws elbv2 modify-listener \
--listener-arn ${{ secrets.ALB_LISTENER_ARN }} \
--default-actions \
Type=forward,TargetGroupArn=${{ secrets.GREEN_TG_ARN }}
メリット: 即座(そくざ)のロールバック可能(かのう)(Blueへトラフィック切替(きりかえ))、ダウンタイムゼロ デメリット: 2倍(ばい)のインフラコスト、データベースマイグレーションが複雑(ふくざつ)
1.3 カナリアデプロイ
少数(しょうすう)のトラフィックに新(あたら)しいバージョンを先(さき)にデプロイして検証(けんしょう)します。
Phase 1: 5%トラフィックをCanary(v2)へ
┌──────────────────────────────┐
│ v1 v1 v1 v1 v1 v1 v1 v1 v1 │ 95%
│ v2 │ 5%
└──────────────────────────────┘
Phase 2: 検証後25%に拡大
┌──────────────────────────────┐
│ v1 v1 v1 v1 v1 v1 v1 │ 75%
│ v2 v2 v2 │ 25%
└──────────────────────────────┘
Phase 3: 安定確認後100%
┌──────────────────────────────┐
│ v2 v2 v2 v2 v2 v2 v2 v2 v2 │ 100%
└──────────────────────────────┘
# Istioを使ったCanary Deployment
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: myapp
spec:
hosts:
- myapp.example.com
http:
- route:
- destination:
host: myapp
subset: stable
weight: 95
- destination:
host: myapp
subset: canary
weight: 5
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: myapp
spec:
host: myapp
subsets:
- name: stable
labels:
version: v1
- name: canary
labels:
version: v2
メリット: リスク最小化(さいしょうか)、実際(じっさい)のトラフィックで検証(けんしょう)、段階的(だんかいてき)ロールアウト デメリット: 実装(じっそう)の複雑(ふくざつ)さ、メトリクスベースの自動化(じどうか)が必要(ひつよう)
1.4 デプロイ戦略比較(ひかく)
| 戦略 | ダウンタイム | ロールバック速度(そくど) | コスト | 複雑度(ふくざつど) | 適(てき)したシナリオ |
|---|---|---|---|---|---|
| Rolling | なし | 遅(おそ)い | 低(ひく)い | 低い | 一般(いっぱん)サービス |
| Blue-Green | なし | 即座(そくざ) | 高(たか)い(2倍(ばい)) | 中程度(ちゅうていど) | 重要(じゅうよう)サービス |
| Canary | なし | 速(はや)い | 中程度 | 高い | 大規模(だいきぼ)トラフィック |
| A/Bテスト | なし | 速い | 中程度 | 非常(ひじょう)に高い | 機能実験(きのうじっけん) |
2. GitOps
2.1 GitOpsの原則(げんそく)
┌──────────────────────────────────────────────────────┐
│ GitOps原則 │
│ │
│ 1. 宣言的 (Declarative) │
│ - システム状態をコードで宣言 │
│ │
│ 2. バージョン管理 (Versioned) │
│ - Gitが唯一の信頼源(SSOT) │
│ │
│ 3. 自動適用 (Automated) │
│ - 承認された変更は自動でシステムに反映 │
│ │
│ 4. 自己修復 (Self-healing) │
│ - 実際の状態と望ましい状態の差異を自動修正 │
└──────────────────────────────────────────────────────┘
2.2 ArgoCD設定(せってい)
# argocd-application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp-production
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/myorg/k8s-manifests.git
targetRevision: main
path: apps/myapp/overlays/production
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true # 不要なリソースを整理
selfHeal: true # 手動変更を自動復旧
allowEmpty: false
syncOptions:
- CreateNamespace=true
- PrunePropagationPolicy=foreground
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
2.3 ArgoCD App-of-Appsパターン
# root-application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: root-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/myorg/k8s-manifests.git
targetRevision: main
path: apps
destination:
server: https://kubernetes.default.svc
# apps/ ディレクトリ構造
# apps/
# myapp/
# application.yaml
# api-gateway/
# application.yaml
# monitoring/
# application.yaml
# cert-manager/
# application.yaml
2.4 ArgoCD vs Flux 比較(ひかく)
| 機能(きのう) | ArgoCD | Flux v2 |
|---|---|---|
| UIダッシュボード | 内蔵(ないぞう)Web UI | Weave GitOps(別途(べっと)) |
| マルチクラスター | サポート | サポート |
| Helmサポート | ネイティブ | HelmRelease CRD |
| Kustomizeサポート | ネイティブ | ネイティブ |
| イメージ自動更新(じどうこうしん) | ArgoCD Image Updater | 内蔵 |
| 通知(つうち) | ArgoCD Notifications | Notification Controller |
| RBAC | 内蔵 | Kubernetes RBAC使用 |
| アプローチ | Pullベース | Pullベース |
| 学習曲線(がくしゅうきょくせん) | 中程度 | 中〜高 |
3. モノレポCI
3.1 モノレポ構造(こうぞう)
monorepo/
apps/
web/ # Next.js フロントエンド
api/ # Express バックエンド
mobile/ # React Native アプリ
packages/
ui/ # 共有UIコンポーネント
utils/ # 共有ユーティリティ
config/ # 共有設定
turbo.json # Turborepo設定
nx.json # またはNx設定
package.json
3.2 Turborepo設定(せってい)
{
"globalDependencies": ["**/.env.*local"],
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**"],
"cache": true
},
"test": {
"dependsOn": ["build"],
"outputs": [],
"cache": true
},
"lint": {
"outputs": [],
"cache": true
},
"deploy": {
"dependsOn": ["build", "test", "lint"],
"cache": false
}
}
}
3.3 Nx影響範囲(えいきょうはんい)ベースのビルド
# .github/workflows/monorepo-ci.yml
name: Monorepo CI
on:
pull_request:
branches: [main]
jobs:
affected:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # 全履歴が必要
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- run: npm ci
# 変更されたプロジェクトのみビルド/テスト
- name: Lint affected
run: npx nx affected --target=lint --base=origin/main
- name: Test affected
run: npx nx affected --target=test --base=origin/main
- name: Build affected
run: npx nx affected --target=build --base=origin/main
# リモートキャッシング
remote-cache:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- name: Build with remote cache
run: npx turbo build --team=myteam --token=${{ secrets.TURBO_TOKEN }}
env:
TURBO_TEAM: myteam
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
3.4 Turborepo vs Nx vs Bazel 比較(ひかく)
| 機能 | Turborepo | Nx | Bazel |
|---|---|---|---|
| 学習曲線(がくしゅうきょくせん) | 低い | 中程度(ちゅうていど) | 高い |
| 言語(げんご)サポート | JS/TS | JS/TS, Go, Rustなど | 多言語(たげんご) |
| 変更検知(へんこうけんち) | ファイルハッシュ | プロジェクトグラフ | 依存(いぞん)グラフ |
| リモートキャッシュ | Vercel RC | Nx Cloud | Remote Execution |
| 設定複雑度(せっていふくざつど) | 非常(ひじょう)にシンプル | 中程度 | 複雑 |
| 大規模(だいきぼ)適合性(てきごうせい) | 中規模(ちゅうきぼ) | 大規模 | 超大規模(ちょうだいきぼ) |
| コード生成 | なし | 内蔵Generator | Rules |
4. Feature Flags(フィーチャーフラグ)
4.1 フィーチャーフラグの種類(しゅるい)
┌──────────────────────────────────────────────────┐
│ Feature Flagの種類 │
├──────────────────────────────────────────────────┤
│ │
│ 1. Release Flag(リリースフラグ) │
│ - 未完成の機能を隠してデプロイ │
│ - 寿命: 短い(数日〜数週間) │
│ │
│ 2. Experiment Flag(実験フラグ) │
│ - A/Bテスト、機能比較 │
│ - 寿命: 中程度(数週間〜数ヶ月) │
│ │
│ 3. Ops Flag(運用フラグ) │
│ - システム動作制御(キルスイッチ) │
│ - 寿命: 永続的 │
│ │
│ 4. Permission Flag(権限フラグ) │
│ - ユーザー/組織別の機能アクセス制御 │
│ - 寿命: 永続的 │
└──────────────────────────────────────────────────┘
4.2 実装(じっそう)例
// featureFlags.ts
import { UnleashClient } from 'unleash-proxy-client';
const unleash = new UnleashClient({
url: 'https://unleash.myapp.com/api/frontend',
clientKey: process.env.UNLEASH_CLIENT_KEY!,
appName: 'myapp-frontend',
refreshInterval: 15,
});
unleash.start();
// React Hook
export function useFeatureFlag(flagName: string): boolean {
const [enabled, setEnabled] = useState(false);
useEffect(() => {
setEnabled(unleash.isEnabled(flagName));
const handler = () => {
setEnabled(unleash.isEnabled(flagName));
};
unleash.on('update', handler);
return () => unleash.off('update', handler);
}, [flagName]);
return enabled;
}
// コンポーネントでの使用
function CheckoutPage() {
const newCheckoutEnabled = useFeatureFlag('new-checkout-flow');
if (newCheckoutEnabled) {
return <NewCheckoutFlow />;
}
return <LegacyCheckoutFlow />;
}
4.3 Progressive Rollout(段階的(だんかいてき)ロールアウト)
// サーバーサイドフィーチャーフラグ (LaunchDarklyスタイル)
import LaunchDarkly from 'launchdarkly-node-server-sdk';
const client = LaunchDarkly.init(process.env.LD_SDK_KEY!);
async function getFeatureValue(
flagKey: string,
user: LDUser,
defaultValue: boolean
): Promise<boolean> {
await client.waitForInitialization();
return client.variation(flagKey, user, defaultValue);
}
// 段階的ロールアウトの設定:
// Phase 1: 社内メンバーのみ (beta-testers グループ)
// Phase 2: 5%のユーザー
// Phase 3: 25%のユーザー
// Phase 4: 50%のユーザー
// Phase 5: 100%のユーザー
// キルスイッチパターン
async function processPayment(order: Order) {
const newPaymentEnabled = await getFeatureValue(
'new-payment-gateway',
{ key: order.userId },
false // デフォルト: 無効
);
if (newPaymentEnabled) {
return newPaymentGateway.process(order);
}
return legacyPaymentGateway.process(order);
}
4.4 LaunchDarkly vs Unleash vs Flagsmith
| 機能 | LaunchDarkly | Unleash | Flagsmith |
|---|---|---|---|
| 価格(かかく) | 有料(ゆうりょう)(高額(こうがく)) | オープンソース + エンタープライズ | オープンソース + クラウド |
| ターゲティング | 非常(ひじょう)に精巧(せいこう) | 基本的(きほんてき) | 精巧 |
| A/Bテスト | 内蔵(ないぞう) | 別途(べっと) | 内蔵 |
| SDKサポート | 25+言語 | 15+言語 | 15+言語 |
| セルフホスティング | 不可(ふか) | 可能(かのう) | 可能 |
| 監査(かんさ)ログ | サポート | サポート | サポート |
5. 環境管理(かんきょうかんり)
5.1 環境階層構造(かいそうこうぞう)
┌─────────────────────────────────────────┐
│ Production(プロダクション) │
│ - 実際のユーザートラフィック │
│ - 最高レベルのモニタリング │
│ - 変更時に承認プロセス │
├─────────────────────────────────────────┤
│ Staging(ステージング) │
│ - プロダクションと同一構成 │
│ - QAチームテスト │
│ - 統合テスト実行 │
├─────────────────────────────────────────┤
│ Development(開発) │
│ - 最新機能の統合 │
│ - mainブランチから自動デプロイ │
├─────────────────────────────────────────┤
│ PR Preview(PRプレビュー) │
│ - PR毎に独立環境を作成 │
│ - PRクローズ時に自動削除 │
└─────────────────────────────────────────┘
5.2 エフェメラル環境(かんきょう)
# .github/workflows/preview.yml
name: PR Preview Environment
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
deploy-preview:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy Preview
run: |
PREVIEW_URL="pr-${{ github.event.number }}.preview.myapp.com"
helm upgrade --install \
pr-${{ github.event.number }} \
./charts/myapp \
--namespace previews \
--set image.tag=${{ github.sha }} \
--set ingress.host=$PREVIEW_URL \
--set resources.requests.memory=256Mi \
--set resources.requests.cpu=100m
- name: Comment PR with URL
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `Preview deployed: https://pr-${context.issue.number}.preview.myapp.com`
})
cleanup-preview:
if: github.event.action == 'closed'
runs-on: ubuntu-latest
steps:
- name: Delete Preview
run: |
helm uninstall pr-${{ github.event.number }} \
--namespace previews
6. パイプラインセキュリティ
6.1 シークレット管理(かんり)
# GitHub Actions - OIDCを使ったAWS認証(長期シークレット不要)
name: Secure Deploy
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# OIDCベースのAWS認証
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/github-actions-role
aws-region: ap-northeast-1
# シークレットスキャン
- name: Scan for secrets
uses: trufflesecurity/trufflehog@v3
with:
path: ./
extra_args: --only-verified
# コンテナイメージスキャン
- name: Scan container image
uses: aquasecurity/trivy-action@master
with:
image-ref: myapp:${{ github.sha }}
severity: 'CRITICAL,HIGH'
exit-code: '1'
6.2 SLSA(Supply-chain Levels for Software Artifacts)
# SLSA Level 3 - 署名付きビルド + 来歴証明
name: SLSA Build
jobs:
build:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
attestations: write
steps:
- uses: actions/checkout@v4
- name: Build
run: npm run build
# Sigstoreを使ったアーティファクト署名
- name: Sign artifact
uses: sigstore/cosign-installer@v3
- name: Sign container image
run: |
cosign sign \
--yes \
myregistry/myapp:${{ github.sha }}
# SLSA来歴証明の生成
- name: Generate SLSA provenance
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.0.0
with:
image: myregistry/myapp
digest: ${{ steps.build.outputs.digest }}
6.3 セキュリティスキャンパイプライン
# .github/workflows/security.yml
name: Security Pipeline
on:
pull_request:
branches: [main]
schedule:
- cron: '0 6 * * 1' # 毎週月曜日 06:00
jobs:
sast:
name: Static Analysis
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Semgrep
uses: semgrep/semgrep-action@v1
with:
config: p/owasp-top-ten
dependency-check:
name: Dependency Audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm audit --audit-level=high
- name: Snyk Test
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
container-scan:
name: Container Security
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build image
run: docker build -t myapp:scan .
- name: Trivy scan
uses: aquasecurity/trivy-action@master
with:
image-ref: myapp:scan
severity: 'CRITICAL,HIGH'
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'trivy-results.sarif'
7. ロールバック戦略(せんりゃく)
7.1 即時(そくじ)ロールバック
# Kubernetesロールバック
# 最後の成功バージョンに即時ロールバック
# kubectl rollout undo deployment/myapp
# GitHub Actions 自動ロールバック
name: Deploy with Auto-Rollback
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy new version
id: deploy
run: |
kubectl set image deployment/myapp \
myapp=myregistry/myapp:${{ github.sha }}
kubectl rollout status deployment/myapp --timeout=300s
- name: Run post-deploy checks
id: healthcheck
run: |
for i in $(seq 1 10); do
STATUS=$(curl -s -o /dev/null -w "%{http_code}" https://myapp.com/health)
if [ "$STATUS" != "200" ]; then
echo "Health check failed: $STATUS"
exit 1
fi
sleep 5
done
- name: Rollback on failure
if: failure()
run: |
echo "Rolling back to previous version..."
kubectl rollout undo deployment/myapp
kubectl rollout status deployment/myapp --timeout=300s
7.2 データベース対応(たいおう)ロールバック
デプロイ過程でDBスキーマ変更がある場合:
1. Forward-Compatibleマイグレーション(安全)
┌─────────────────────────────────────┐
│ Step 1: 新カラム追加 (nullable) │
│ Step 2: アプリv2デプロイ (両方使用) │
│ Step 3: データマイグレーション │
│ Step 4: 旧カラム削除 │
└─────────────────────────────────────┘
2. Expand-Contractパターン
Phase 1 (Expand): 新スキーマ追加、既存維持
Phase 2 (Migrate): データ移行
Phase 3 (Contract): 旧スキーマ削除
7.3 Forward-Fix vs ロールバック判断基準(はんだんきじゅん)
| 状況(じょうきょう) | 推奨戦略(すいしょうせんりゃく) | 理由(りゆう) |
|---|---|---|
| 単純(たんじゅん)なバグ修正(しゅうせい) | Forward-Fix | ロールバックより修正(しゅうせい)が速(はや)い |
| 深刻(しんこく)な障害(しょうがい) | 即時ロールバック | サービス復旧(ふっきゅう)が最優先(さいゆうせん) |
| DBマイグレーション含(ふく)む | Forward-Fix | ロールバック時(じ)にデータ損失(そんしつ)リスク |
| パフォーマンス低下(ていか) | カナリアロールバック | 影響範囲(えいきょうはんい)把握後(はあくご)に判断(はんだん) |
8. パイプラインパフォーマンス最適化(さいてきか)
8.1 キャッシング戦略
# .github/workflows/optimized-ci.yml
name: Optimized CI
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Node.js依存関係キャッシング
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
# Dockerレイヤーキャッシング
- uses: docker/setup-buildx-action@v3
- uses: docker/build-push-action@v6
with:
context: .
push: true
tags: myapp:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
# Turborepoリモートキャッシング
- name: Build with cache
run: npx turbo build --cache-dir=.turbo
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: myteam
8.2 並列化(へいれつか)戦略
# 並列ジョブ実行
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm run lint
unit-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm run test:unit
type-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm run type-check
# すべての検証通過後にビルド
build:
needs: [lint, unit-test, type-check]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm run build
9. リリース管理(かんり)
9.1 セマンティックバージョニング
MAJOR.MINOR.PATCH(例: 2.1.3)
MAJOR: 互換性のないAPI変更
MINOR: 下位互換の新機能追加
PATCH: 下位互換のバグ修正
例:
1.0.0 -> 1.0.1 (バグ修正)
1.0.1 -> 1.1.0 (新機能追加)
1.1.0 -> 2.0.0 (Breaking Change)
9.2 自動(じどう)リリースノート
# .github/workflows/release.yml
name: Release
on:
push:
tags: ['v*']
permissions:
contents: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Generate Changelog
id: changelog
uses: orhun/git-cliff-action@v3
with:
config: cliff.toml
- name: Create Release
uses: softprops/action-gh-release@v2
with:
body: ${{ steps.changelog.outputs.content }}
draft: false
prerelease: false
9.3 Conventional Commits
# コミットメッセージ形式
# type(scope): description
feat(auth): add OAuth2.0 login support
fix(cart): resolve quantity update race condition
docs(api): update REST API documentation
chore(deps): upgrade express to v5.0
perf(db): optimize query for order listing
refactor(payment): extract payment strategy pattern
test(checkout): add E2E tests for checkout flow
# Breaking Change表記
feat(api)!: change response format for /orders endpoint
BREAKING CHANGE: The orders endpoint now returns
paginated responses instead of a flat array.
9.4 Release Trainモデル
┌─────────────────────────────────────────────┐
│ Release Train(隔週リリース) │
│ │
│ Week 1: 機能開発 + コードフリーズ │
│ Week 2: QA + バグ修正 + リリース │
│ │
│ --+------+------+------+------+-- │
│ v2.1 v2.2 v2.3 v2.4 v2.5 │
│ │
│ ホットフィックスは別ブランチから即時デプロイ │
└─────────────────────────────────────────────┘
10. マルチクラウドデプロイ
10.1 Terraformを使(つか)ったマルチクラウド
# main.tf - マルチクラウドプロバイダー
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
google = {
source = "hashicorp/google"
version = "~> 5.0"
}
}
}
# AWSデプロイ
resource "aws_ecs_service" "primary" {
name = "myapp-primary"
cluster = aws_ecs_cluster.main.id
task_definition = aws_ecs_task_definition.app.arn
desired_count = 3
load_balancer {
target_group_arn = aws_lb_target_group.app.arn
container_name = "myapp"
container_port = 8080
}
}
# GCPデプロイ (DR)
resource "google_cloud_run_service" "failover" {
name = "myapp-failover"
location = "asia-northeast1"
template {
spec {
containers {
image = "gcr.io/myproject/myapp:latest"
}
}
}
}
11. 実践(じっせん)クイズ
Q1: Blue-Greenデプロイの最大のメリットは?
A) インフラコストが安い B) 即座にロールバックできる C) 実装が簡単 D) トラフィック分割ができる
正解(せいかい): B
Blue-Greenデプロイは2つの同一(どういつ)環境(かんきょう)を維持(いじ)するため、問題(もんだい)発生時(はっせいじ)にロードバランサーのトラフィックを以前(いぜん)の環境(Blue)に即座(そくざ)に切(き)り替(か)えてロールバックできます。ただし2倍(ばい)のインフラコストがデメリットです。
Q2: GitOpsにおけるGitリポジトリの役割は?
A) コードバックアップストレージ B) CI/CDパイプライン実行エンジン C) インフラの唯一の信頼源(SSOT) D) モニタリングダッシュボード
正解: C
GitOpsではGitリポジトリがインフラとアプリケーション状態(じょうたい)の唯一(ゆいいつ)の信頼源(しんらいげん)(Single Source of Truth)です。すべての変更(へんこう)はGitを通(とお)して行(おこな)われ、ArgoCD/Fluxなどのツールが Git状態と実際(じっさい)のクラスター状態を同期(どうき)します。
Q3: モノレポCIでの「affected」ビルドのメリットは?
A) すべてのプロジェクトを常にビルドする B) 変更されたプロジェクトと影響を受けるプロジェクトのみビルドし時間を節約する C) ビルドキャッシュを無視する D) テストをスキップする
正解: B
「affected」ビルドはGit diffを分析(ぶんせき)して、変更(へんこう)されたプロジェクトとそれに依存(いぞん)するプロジェクトのみを選択的(せんたくてき)にビルド/テストします。これにより大規模(だいきぼ)モノレポでのCI時間(じかん)を大幅(おおはば)に短縮(たんしゅく)できます。
Q4: Feature Flagの「キルスイッチ」の用途は?
A) サーバーをシャットダウンする B) 問題のある機能をコードデプロイなしで即座に無効化する C) データベースを削除する D) CIパイプラインを停止する
正解: B
キルスイッチは、プロダクションで問題(もんだい)が発生(はっせい)した際(さい)に、新(あたら)しいコードのデプロイなしでフィーチャーフラグをOFFに切(き)り替(か)えて、該当機能(がいとうきのう)を即座(そくざ)に無効化(むこうか)するパターンです。ロールバックよりはるかに速(はや)く対応(たいおう)できます。
Q5: SLSA(Supply-chain Levels for Software Artifacts)の目的は?
A) コードパフォーマンス最適化 B) ソフトウェアサプライチェーンの完全性を保証する C) データベースセキュリティ D) UIデザイン検証
正解: B
SLSAはソフトウェアサプライチェーン攻撃(こうげき)を防止(ぼうし)するためのセキュリティフレームワークです。ビルドプロセスの来歴証明(らいれきしょうめい)、アーティファクト署名(しょめい)、ビルド環境(かんきょう)の分離(ぶんり)などを通(つう)じて、ソフトウェアが改竄(かいざん)されていないことを保証(ほしょう)します。
12. CI/CD成熟度(せいじゅくど)チェックリスト
CI/CD成熟度チェックリスト:
Level 1 - 基本
[ ] 自動ビルドパイプライン
[ ] 自動テスト実行
[ ] コードレビュープロセス
Level 2 - 標準
[ ] デプロイ戦略(Rolling/Blue-Green)
[ ] 環境分離(dev/staging/prod)
[ ] シークレット管理(Vault/OIDC)
Level 3 - 上級
[ ] GitOps(ArgoCD/Flux)
[ ] Feature Flags
[ ] カナリアデプロイ
[ ] PRプレビュー環境
Level 4 - エリート
[ ] パイプラインセキュリティ(SLSA)
[ ] 自動ロールバック
[ ] モノレポ最適化
[ ] リリース自動化
13. 参考資料(さんこうしりょう)
- DORA Metrics: dora.dev
- ArgoCD Documentation: argo-cd.readthedocs.io
- Flux Documentation: fluxcd.io
- Turborepo Documentation: turbo.build
- Nx Documentation: nx.dev
- LaunchDarkly Docs: docs.launchdarkly.com
- Unleash Documentation: docs.getunleash.io
- SLSA Framework: slsa.dev
- Sigstore / Cosign: sigstore.dev
- Semgrep: semgrep.dev
- Conventional Commits: conventionalcommits.org
- Git Cliff (Changelog): git-cliff.org
- GitHub Actions Docs: docs.github.com/actions
- Kubernetes Deployment Strategies: kubernetes.io/docs