LESSON 30分

ストーリー

佐藤CTO
アーキテクチャの技術的なトレードオフは分析できるようになった。次は”お金”の話だ
佐藤CTO
経営層に設計を提案するとき、“技術的に優れている”だけでは不十分だ。“いくらかかるのか”、“リスクは何か”、“投資対効果はどうか”を語れなければならない
佐藤CTO
アーキテクトは技術とビジネスの橋渡し役だ。コスト意識を持つことで、信頼される提案ができるようになる

TCO(Total Cost of Ownership)

TCOとは

TCO は「総所有コスト」— ある選択肢を採用してから廃棄するまでのすべてのコストの合計です。

TCO = 初期コスト + 運用コスト + 保守コスト + 廃棄コスト

┌──────────┬──────────┬──────────┬──────────┐
│  初期    │  運用    │  保守    │  廃棄    │
│          │          │          │          │
│ 開発費   │ インフラ  │ バグ修正  │ 移行費   │
│ ライセンス│ 監視     │ 機能追加  │ データ移行│
│ 教育費   │ サポート  │ セキュリティ│ 並行運用 │
│ 環境構築 │ バックアップ│ アップデート│ 廃止作業 │
└──────────┴──────────┴──────────┴──────────┘
     Year 0      Year 1-3      Year 3-5      Year 5+

TCO計算の例

interface TCOCalculation {
  option: string;
  initialCosts: {
    development: number;      // 開発費
    licensing: number;        // ライセンス費
    training: number;         // 教育費
    infrastructure: number;   // 初期インフラ構築費
  };
  annualCosts: {
    infrastructure: number;   // インフラ運用費(年間)
    maintenance: number;      // 保守費(年間)
    support: number;          // サポート費(年間)
    licensing: number;        // ライセンス更新費(年間)
  };
  projectedYears: number;     // 計算期間
}

function calculateTCO(calc: TCOCalculation): number {
  const initial = Object.values(calc.initialCosts)
    .reduce((sum, cost) => sum + cost, 0);
  const annual = Object.values(calc.annualCosts)
    .reduce((sum, cost) => sum + cost, 0);
  return initial + annual * calc.projectedYears;
}

// 比較例:自社構築 vs SaaS
const buildOption: TCOCalculation = {
  option: "自社構築",
  initialCosts: {
    development: 30_000_000,   // 3000万円(6名×5ヶ月)
    licensing: 0,
    training: 1_000_000,
    infrastructure: 2_000_000,
  },
  annualCosts: {
    infrastructure: 3_600_000, // 月30万円×12
    maintenance: 6_000_000,    // 1名分の保守工数
    support: 0,
    licensing: 0,
  },
  projectedYears: 3,
};

const saasOption: TCOCalculation = {
  option: "SaaS利用",
  initialCosts: {
    development: 5_000_000,    // カスタマイズ開発
    licensing: 0,
    training: 500_000,
    infrastructure: 0,
  },
  annualCosts: {
    infrastructure: 0,
    maintenance: 1_200_000,    // カスタマイズ保守
    support: 0,
    licensing: 6_000_000,      // SaaSライセンス年間
  },
  projectedYears: 3,
};

// 自社構築TCO: 33,000,000 + 9,600,000 × 3 = 61,800,000円
// SaaS利用TCO:  5,500,000 + 7,200,000 × 3 = 27,100,000円

クラウドコスト見積もり

AWS コスト構成の主要要素

graph TD
    AWS["AWSコストの主要カテゴリ"]
    A["コンピュート<br/>EC2, Lambda, ECS, Fargate"]
    B["ストレージ<br/>S3, EBS, EFS"]
    C["データベース<br/>RDS, DynamoDB, ElastiCache"]
    D["ネットワーク<br/>データ転送, CloudFront, ALB"]
    E["その他<br/>CloudWatch, Route53, KMS"]

    AWS --> A
    AWS --> B
    AWS --> C
    AWS --> D
    AWS --> E

    classDef titleStyle fill:#2c5f8a,stroke:#1a3d5c,color:#fff
    classDef catStyle fill:#e8a838,stroke:#b07c1e,color:#fff

    class AWS titleStyle
    class A,B,C,D,E catStyle

コスト見積もりの考え方

// Webアプリケーションの月額コスト見積もり例
interface MonthlyCloudCost {
  compute: {
    service: string;
    specs: string;
    monthlyCost: number;
  }[];
  database: {
    service: string;
    specs: string;
    monthlyCost: number;
  }[];
  storage: {
    service: string;
    specs: string;
    monthlyCost: number;
  }[];
  network: {
    description: string;
    monthlyCost: number;
  }[];
  other: {
    description: string;
    monthlyCost: number;
  }[];
}

// 中規模Webアプリの見積もり例
const estimate: MonthlyCloudCost = {
  compute: [
    { service: "ECS Fargate", specs: "2vCPU/4GB × 3タスク", monthlyCost: 45_000 },
    { service: "Lambda", specs: "月100万リクエスト", monthlyCost: 3_000 },
  ],
  database: [
    { service: "RDS PostgreSQL", specs: "db.r6g.large × 2 (Multi-AZ)", monthlyCost: 80_000 },
    { service: "ElastiCache Redis", specs: "cache.r6g.large × 2", monthlyCost: 55_000 },
  ],
  storage: [
    { service: "S3", specs: "500GB + 月500万リクエスト", monthlyCost: 5_000 },
    { service: "EBS", specs: "gp3 100GB × 3", monthlyCost: 3_000 },
  ],
  network: [
    { description: "ALB", monthlyCost: 8_000 },
    { description: "CloudFront", monthlyCost: 12_000 },
    { description: "データ転送 500GB/月", monthlyCost: 7_000 },
  ],
  other: [
    { description: "CloudWatch", monthlyCost: 5_000 },
    { description: "Route53", monthlyCost: 1_000 },
    { description: "ACM, KMS等", monthlyCost: 2_000 },
  ],
};

// 月額合計: 約226,000円(年間約271万円)

スケーリング時のコスト変化

スケールユーザー数月額目安備考
スモール~1,000 DAU5-10万円最小構成
ミディアム~10,000 DAU20-40万円Multi-AZ, キャッシュ追加
ラージ~100,000 DAU100-200万円オートスケーリング、CDN
エンタープライズ~1,000,000 DAU500万円~マルチリージョン

リスク評価マトリクス

リスクの定量化

確率(Probability)

高│  ③注意    ⑤重大    ⑤重大

中│  ②低      ③注意    ⑤重大

低│  ①無視可  ②低      ③注意

  └──────────────────────────▶ 影響度(Impact)
       低       中       高

リスク評価テンプレート

interface RiskAssessment {
  id: string;
  category: "TECHNICAL" | "OPERATIONAL" | "BUSINESS" | "SECURITY";
  description: string;
  probability: 1 | 2 | 3 | 4 | 5;  // 1=極低 ~ 5=極高
  impact: 1 | 2 | 3 | 4 | 5;       // 1=極低 ~ 5=極高
  riskScore: number;                 // probability × impact
  mitigation: string;
  contingency: string;               // リスク発生時の対応
  owner: string;
}

const risks: RiskAssessment[] = [
  {
    id: "R-001",
    category: "TECHNICAL",
    description: "マイクロサービス間の通信障害によるカスケード障害",
    probability: 3,
    impact: 5,
    riskScore: 15,
    mitigation: "サーキットブレーカーパターンの導入、タイムアウト設定",
    contingency: "障害サービスの自動切り離し、フォールバック応答",
    owner: "インフラチーム",
  },
  {
    id: "R-002",
    category: "OPERATIONAL",
    description: "Kubernetes運用経験不足による障害対応の遅延",
    probability: 4,
    impact: 3,
    riskScore: 12,
    mitigation: "チーム教育、ランブック整備、段階的導入",
    contingency: "外部SREコンサルタントとの契約",
    owner: "SREチーム",
  },
  {
    id: "R-003",
    category: "BUSINESS",
    description: "SaaSベンダーの価格改定による運用コスト増大",
    probability: 3,
    impact: 3,
    riskScore: 9,
    mitigation: "年間契約での価格固定、代替サービスの事前検証",
    contingency: "代替サービスへの移行計画を事前に準備",
    owner: "プロダクトマネージャー",
  },
];

リスク軽減戦略

4つの基本戦略

graph TD
    R["リスク対応の4戦略"]
    A["回避(Avoid)<br/>リスクの原因を排除する<br/>例: その技術を使わない選択"]
    B["軽減(Mitigate)<br/>確率または影響度を下げる<br/>例: 冗長構成、テストの追加"]
    C["転嫁(Transfer)<br/>リスクを第三者に移す<br/>例: マネージドサービスの利用"]
    D["受容(Accept)<br/>リスクを認識した上で許容する<br/>例: 影響が軽微でコスト対効果が低い"]

    R --> A
    R --> B
    R --> C
    R --> D

    classDef titleStyle fill:#2c5f8a,stroke:#1a3d5c,color:#fff
    classDef avoidStyle fill:#d9534f,stroke:#b52b27,color:#fff
    classDef mitigateStyle fill:#e8a838,stroke:#b07c1e,color:#fff
    classDef transferStyle fill:#4a90d9,stroke:#2c5f8a,color:#fff
    classDef acceptStyle fill:#5cb85c,stroke:#3d8b3d,color:#fff

    class R titleStyle
    class A avoidStyle
    class B mitigateStyle
    class C transferStyle
    class D acceptStyle

戦略選択の基準

リスクスコア推奨戦略
20-25回避実績のない技術の採用を見送る
12-19軽減冗長構成、フォールバック設計
6-11転嫁 or 軽減マネージドサービスの利用
1-5受容影響が軽微な既知の制約

Build vs Buy コスト分析

判断フレームワーク

interface BuildVsBuyCostAnalysis {
  option: "BUILD" | "BUY";
  directCosts: {
    initial: number;          // 初期費用
    annual: number;           // 年間費用
    scaling: string;          // スケール時のコスト変化
  };
  indirectCosts: {
    opportunityCost: string;  // 機会費用(他に何ができたか)
    learningCost: string;     // 学習・教育コスト
    riskCost: string;         // リスクに対するコスト
  };
  hiddenCosts: string[];      // 見落としがちなコスト
}

const buildAnalysis: BuildVsBuyCostAnalysis = {
  option: "BUILD",
  directCosts: {
    initial: 30_000_000,
    annual: 9_600_000,
    scaling: "開発者の追加採用が必要、段階的にコスト増加",
  },
  indirectCosts: {
    opportunityCost: "開発チームが6ヶ月間プロダクト開発に集中できない",
    learningCost: "セキュリティ専門知識の獲得に3ヶ月",
    riskCost: "セキュリティ脆弱性のリスク、障害時の責任",
  },
  hiddenCosts: [
    "セキュリティ監査への対応費用",
    "コンプライアンス認証取得費用",
    "エンジニアの採用・退職リスク",
    "ドキュメンテーション・引き継ぎ費用",
  ],
};

const buyAnalysis: BuildVsBuyCostAnalysis = {
  option: "BUY",
  directCosts: {
    initial: 5_500_000,
    annual: 7_200_000,
    scaling: "ユーザー数に比例して課金が増加",
  },
  indirectCosts: {
    opportunityCost: "カスタマイズの制約によるUX妥協",
    learningCost: "SaaS固有のAPIとワークフローの学習",
    riskCost: "ベンダーロックイン、価格改定リスク",
  },
  hiddenCosts: [
    "API利用制限超過時の追加費用",
    "データエクスポートの制約",
    "SLA違反時のビジネス影響",
    "カスタムインテグレーション開発費",
  ],
};

インフラコスト最適化パターン

よく使われるコスト最適化手法

パターン効果適用場面
リザーブドインスタンス30-60%削減安定したワークロード
スポットインスタンス60-90%削減バッチ処理、中断可能なタスク
オートスケーリング変動に応じた最適化トラフィックが変動するアプリ
適切なインスタンスサイズ20-40%削減過剰プロビジョニング時
サーバーレス移行アイドル時ゼロ低頻度・不規則なワークロード
データ階層化50-80%削減アクセス頻度が低いデータ
// コスト最適化の判断例
interface CostOptimizationDecision {
  pattern: string;
  currentMonthlyCost: number;
  optimizedMonthlyCost: number;
  savingsPercent: number;
  implementationEffort: "LOW" | "MEDIUM" | "HIGH";
  risk: string;
}

const optimizations: CostOptimizationDecision[] = [
  {
    pattern: "RDS リザーブドインスタンス(1年)",
    currentMonthlyCost: 80_000,
    optimizedMonthlyCost: 50_000,
    savingsPercent: 37.5,
    implementationEffort: "LOW",
    risk: "利用計画の変更があった場合に無駄が発生",
  },
  {
    pattern: "バッチ処理をSpotインスタンスに移行",
    currentMonthlyCost: 30_000,
    optimizedMonthlyCost: 6_000,
    savingsPercent: 80,
    implementationEffort: "MEDIUM",
    risk: "インスタンス中断時のリトライロジックが必要",
  },
  {
    pattern: "低頻度APIをLambdaに移行",
    currentMonthlyCost: 45_000,
    optimizedMonthlyCost: 3_000,
    savingsPercent: 93,
    implementationEffort: "HIGH",
    risk: "コールドスタートによるレイテンシ増加",
  },
];

まとめ

ポイント内容
TCO初期費用だけでなく運用・保守・廃棄までの総コスト
クラウドコスト主要サービスの見積もりとスケール時の変化を把握
リスク評価確率 x 影響度でスコア化し、対応戦略を選択
軽減戦略回避・軽減・転嫁・受容の4つの基本戦略
Build vs Buy直接コスト、間接コスト、隠れコストを含めて比較
コスト最適化リザーブド、スポット、サーバーレス等を適切に活用

チェックリスト

  • TCOの構成要素を挙げて計算できる
  • クラウドインフラのコスト見積もりができる
  • リスク評価マトリクスを作成できる
  • リスク軽減の4戦略を適切に選択できる
  • Build vs Buyの比較に隠れコストを含められる

次のステップへ

次は ADR(Architecture Decision Records)を学びます。分析した結果をどのように記録し、チームで共有するかを理解しましょう。


推定読了時間: 30分