目次
27 章

コスト最適化とダッシュボード

Cost Explorer 分析、Savings Plans / Spot / Graviton、Right Sizing、タグ付けの強制とコスト分類、FinOps 領域まで。運用システムのコストを実際に減らすパターンを整理し、4部「コンソールからコードへ」を締めくくります。

第22章 ~ 第26章 でインフラ / DB / CI/CD / IaC / モニタリングまで — 運用可能なシステムが整いました。最後に残ったテーマはどれだけかかっているか、そしてそのコストをどう減らすかです。

本章は4部「コンソールからコードへ」の最後です。第3章 コスト管理 で請求アラートと Cost Explorer の基本を押さえたとすれば、本章はその上で運用システムのコストを実際に減らす段階です。そして章の終わりで、これまで積み上げたレイヤーを一度整理し、5部 運用・セキュリティ・コストへ渡る橋を架けます。

請求書がどこから漏れるか #

典型的な小さな運用(ECS Fargate + RDS + ALB + CloudFront + Logs)の月の請求書の比率は次のとおりです。

資源比率意味
ECS Fargate (vCPU + メモリ時間)30 ~ 50%最も大きなコスト項目
RDS (インスタンス + Storage + IO)20 ~ 30%Multi-AZ なら 2x
NAT Gateway / Egress10 ~ 20%よく忘れられるコスト項目
ALB / トラフィック5 ~ 10%時間 + LCU
CloudWatch Logs / Metrics5 ~ 10%retention 欠落時に暴走
S3 / ECR2 ~ 5%イメージ / オブジェクトの累積
その他5%DNS, KMS, Secrets, …

この表を見て「自分の請求書に似ている」と思ったら、次のパターンが効きます。

1) Cost Explorer — どこでお金が出ていくかから #

Cost Explorer が請求書をスライス / ダイスします。コンソールでよく使う分析は次のとおりです。

よく使う分析
1) サービス別      — Fargate vs RDS vs Logs (最も大きなコスト項目)
2) タグ別          — env=prod vs env=dev (環境分離のコスト)
3) 使用タイプ別      — DataTransfer-Out-Bytes vs BoxUsage など
4) リージョン別      — 眠っている別リージョンの資源 (1章の落とし穴)
5) 時系列の推移      — 昨日から急に上がった項目

CLI でも #

今月のサービス別コスト
aws ce get-cost-and-usage \
  --time-period Start=$(date -u +%Y-%m-01),End=$(date -u +%Y-%m-%d) \
  --granularity DAILY \
  --metrics BlendedCost \
  --group-by Type=DIMENSION,Key=SERVICE

Cost Anomaly Detection #

ML ベースの異常値検知です。普段のパターンから外れると自動で知らせます。

異常値モニター (サービス単位)
aws ce create-anomaly-monitor \
  --anomaly-monitor '{
    "MonitorName": "blog-services",
    "MonitorType": "DIMENSIONAL",
    "MonitorDimension": "SERVICE"
  }'

第3章 コスト管理 の請求アラートが「閾値を超えたら」なら、Cost Anomaly は「普段と違ったら」です。微妙な漏れを掴む道具です。

2) Compute コスト — Fargate の三つのポイント #

A) Right Sizing — 本当に必要な分だけ #

CloudWatch Container Insights(第26章)の平均 CPU / メモリ使用率を見て task サイズを調整します。

Right Sizing の例
現在: cpu=1024, memory=2048
観察: 平均 CPU 15%, p95 35%, メモリ平均 30%
調整: cpu=512, memory=1024  → コスト 50% 削減

CPU 平均が 30 ~ 50% の領域で回るのが健康な水準です。20% 未満なら大きすぎます(それでも burst の余裕は残します)。

小さな環境では Compute Optimizer が自動で推薦をしてくれます。コンソールで一度オンにすればよいです。

B) Fargate Spot — 70% 安価 #

バッチ性 / 再起動可能な task は Fargate Spot で回します。

capacity provider strategy
resource "aws_ecs_service" "this" {
  capacity_provider_strategy {
    capacity_provider = "FARGATE"
    weight            = 1     # base on-demand
    base              = 2
  }

  capacity_provider_strategy {
    capacity_provider = "FARGATE_SPOT"
    weight            = 4     # 追加は Spot 優先
  }
}

上のパターンは常に2個は on-demand、それ以上は 4:1 の比率で Spot です。負荷が減れば Spot から整理します。

中断 (interruption) が発生すると ECS が新しい task を立ち上げますが、~120秒のダウンタイムがありえます。運用トラフィックでは一部だけ Spot に置き、100% Spot は大きな危険です。

C) Graviton (ARM) — 20% 安価 + 20% 速い #

db.t4g.*(RDS)、Fargate ARM オプション、EC2 Graviton(m7gc7g)は AWS の ARM チップです。コンテナイメージが ARM ビルド可能なら、わざわざ使わない理由がありません。

Multi-arch ビルド
# ビルド
docker buildx build --platform linux/amd64,linux/arm64 \
  -t $REPO/blog-api:v1 --push .
Fargate ARM 64
resource "aws_ecs_task_definition" "this" {
  cpu          = "512"
  memory       = "1024"
  runtime_platform {
    cpu_architecture       = "ARM64"
    operating_system_family = "LINUX"
  }
}

前提は、使うライブラリがすべて ARM 互換でなければならないという点です。ほとんどの Python / Node / Go パッケージは OK です。一部の native bindings は検証が必要です。

3) Savings Plans / Reserved Capacity #

Fargate / EC2 / Lambda の約定割引です。

種類割引約定
Compute Savings Plan最大 66%1年 / 3年、$/h 約定
EC2 Instance SP最大 72%インスタンスファミリーまで約定
RDS Reserved最大 65%インスタンスクラス + リージョン

Compute SP が最も柔軟です(Fargate / EC2 / Lambda すべてに適用)。安定運用に入った時点から検討します。最初は絶対に約定しません(トラフィック / アーキテクチャが揺れているとき)。

ガイド
運用開始 ~ 3か月     : 約定 X (変化の速い環境)
3か月 ~ 6か月         : 使用量を分析、1年 SP の検討を開始
6か月 +              : 安定した使用量の 60~70% の分だけ1年約定

全体の 100% を約定するとトラフィックが減ったときに損です。常に安全マージンを残します。

4) Storage / Logs — 最もよく漏れる項目 #

CloudWatch Logs #

第26章 で強調した retention です。すべてのグループに適用します。

Terraform で一括 30日
resource "aws_cloudwatch_log_group" "ecs" {
  for_each          = toset(["/ecs/blog-api", "/ecs/blog-api-migrate"])
  name              = each.key
  retention_in_days = 30
}

S3 #

古いオブジェクトを自動で安価なクラスへ移します。

S3 lifecycle
resource "aws_s3_bucket_lifecycle_configuration" "logs" {
  bucket = aws_s3_bucket.logs.id
  rule {
    id     = "to-ia-then-glacier"
    status = "Enabled"
    transition { days = 30,  storage_class = "STANDARD_IA" }
    transition { days = 90,  storage_class = "GLACIER" }
    expiration { days = 365 }
  }
}

ECR #

古いイメージを自動で削除します。

ECR lifecycle
resource "aws_ecr_lifecycle_policy" "blog_api" {
  repository = aws_ecr_repository.blog_api.name
  policy = jsonencode({
    rules = [{
      rulePriority = 1
      description  = "最近の30個だけ維持"
      selection    = { tagStatus = "any", countType = "imageCountMoreThan", countNumber = 30 }
      action       = { type = "expire" }
    }]
  })
}

5) Network — NAT と Egress #

運用の請求書を初めて見る人が最も驚く項目は NAT Gateway と Egress です。

NAT Gateway のコスト
時間あたり  $0.045
GB あたり   $0.045   (処理)
+ Egress $0.09/GB (インターネットへ)

小さなシステムでも NAT 一つが月 ~$32 + トラフィックです。パターン別の節約は次のとおりです。

パターン効果
VPC Endpoint for S3, DynamoDB完全無料、NAT トラフィックを分散
VPC Endpoint for ECR, Logs, Secrets時間あたり ~$0.01 + GB ~$0.01(NAT より安価)
CloudFront を前に置くOrigin → CloudFront 無料、CloudFront → ユーザー GB ~$0.085(地域による)
単一 NAT(開発環境)AZ ごとの NAT ではなく一つの NAT — 可用性 ↓

Endpoint 一行 #

ECR Interface Endpoint
resource "aws_vpc_endpoint" "ecr_api" {
  vpc_id              = aws_vpc.this.id
  service_name        = "com.amazonaws.${var.region}.ecr.api"
  vpc_endpoint_type   = "Interface"
  subnet_ids          = aws_subnet.private[*].id
  security_group_ids  = [aws_security_group.endpoints.id]
  private_dns_enabled = true
}

ECS task が ECR からイメージを受け取るとき、NAT ではなく endpoint を通じて受け取ります。NAT トラフィックとコストの両方を削減します。

6) タグ付け — コストを分類可能にする #

タグがないと請求書が一塊です。タグがあれば環境 / チーム / プロジェクト別にスライスされます。

基本タグ
provider "aws" {
  default_tags {
    tags = {
      Environment = var.environment
      Project     = "blog-api"
      ManagedBy   = "terraform"
      CostCenter  = "product-blog"
    }
  }
}

providerdefault_tagsすべての資源に自動適用されます。運用の核心です。

Cost Allocation Tag の有効化 #

タグを入れても、コンソールの Billing → Cost Allocation Tags で有効化しないと Cost Explorer が分類してくれません。設定 → タグ有効化 → ~24h 待機 → 使用可能、の順序です。

タグの強制 (SCP / IAM Condition) #

タグのない資源の生成を遮断します。AWS Organizations の SCP または IAM ポリシーの Condition で行います。

タグがなければ生成を拒否
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Deny",
    "Action": ["ec2:RunInstances", "rds:CreateDBInstance"],
    "Resource": "*",
    "Condition": {
      "Null": { "aws:RequestTag/Environment": "true" }
    }
  }]
}

SCP と Organizations 次元のガバナンスは 第29章 セキュリティガバナンス で本格的に扱います。

7) 運用コストダッシュボード #

CloudWatch Dashboard にコストウィジェットを一行加えます。

コストダッシュボードのウィジェット
[1] 今月の累積コスト (vs 先月の同時点)
[2] サービス別 (Fargate / RDS / Logs / NAT / ALB)
[3] 環境別 (env=prod vs env=staging vs env=dev)
[4] 日次推移 (90日)
[5] Right Sizing 推薦数

毎週一度 oncall 会議で30分あれば、悪くなる指標を早期に発見できます。

分担責任 — FinOps #

大きな組織は FinOps という専任の領域が別にあってコストを見ます。小さな組織では開発者本人が自分のモジュールのコストを意識しなければなりません。タグがそれゆえ核心です。自分のコードの請求書を自分で見られなければ意識が生まれません。

落とし穴 — コストでよく出会う落とし穴 #

1) 眠っている別リージョンの資源 #

第1章 AWS 入門 の落とし穴そのままです。AWS Resource Explorer または Cost Explorer のリージョン別コストで、0 でないリージョンを点検します。

2) terraform destroy していない PoC #

スタック / 環境を作って忘れる失敗です。タグ + 自動清掃ラムダパターンで防ぎます。

自動清掃
EventBridge schedule (毎日午前9時)
Lambda
   - tag Project=PoC AND CreatedAt < 7 days ago
   - 資源削除 / 通知

3) Free Tier の満了を知らない #

第3章 コスト管理 の請求アラートが第一防衛線で、Cost Anomaly Detection が二番目です。

4) 100% Spot で運用ダウンタイム #

Spot interruption が一度に複数の task にかかると、service が desired count を満たせず 5xx が暴走します。常に base on-demand を残します。

5) Multi-AZ RDS の二倍 #

小さなシステムには Multi-AZ がコスト負担です。かといって単一 AZ も困ります。折衷は dev/staging 単一 AZ + prod Multi-AZ です。

6) VPC Endpoint 未使用 #

NAT だけ使う単純なセットアップだと、トラフィックの大きな資源(Logs、S3)が NAT を経由してコストが暴走します。運用に入る時点で必ず検討します。

7) 約定後のアーキテクチャ変更 #

3年 SP を買った直後に ARM / Lambda へ移すと、約定はそのまま請求されます。短い(1年)約定から、安定した環境でのみ行います。

4部で積み上げたレイヤー #

ここまでが4部「コンソールからコードへ」です。1 ~ 3部で身につけた道具たちが、4部で一つのシステムとして積み上がりました。

この本で積み上げたレイヤー
        ┌─────────────────────────────────────┐
        │ FinOps                              │   ← 27章
        │ コスト / タグ付け / 約定             │
        ├─────────────────────────────────────┤
        │ 可観測性                             │   ← 26章
        │ Logs / Metrics / Traces             │
        ├─────────────────────────────────────┤
        │ 自動化                                │   ← 24, 25章
        │ CI/CD / IaC                         │
        ├─────────────────────────────────────┤
        │ データ                                │   ← 23章 + 11章
        │ RDS / Secrets                       │
        ├─────────────────────────────────────┤
        │ コンピューティング                     │   ← 22章 + 15~21章
        │ ECS / Lambda                        │
        ├─────────────────────────────────────┤
        │ ネットワーク                          │   ← 8, 13, 14章
        │ VPC / ALB / CloudFront              │
        ├─────────────────────────────────────┤
        │ コントロールプレーン                   │   ← 1~7章
        │ アカウント / IAM / コスト / セキュリティ │
        └─────────────────────────────────────┘

上のレイヤーを逆に — コントロール → ネットワーク → コンピューティング → データ → 自動化 → 観測 → FinOps — が運用の自然な進化の順序です。新しいシステムを作るたびにこの流れを再び辿ることになります。

4部まで追ってきた方なら、小さなバックエンドを ECS Fargate の上に運用可能な形で載せ、コードで再現し、自動でデプロイし、観測し、コストを制御する一周りを手に入れたことになります。次の5部は、このシステムがさらに大きくなったとき — ネットワークをより深く設計し、マルチアカウントでガバナンスを立て、障害に備える — 運用・セキュリティ・コストの話へつながります。

練習問題 #

  1. §「請求書がどこから漏れるか」の比率の表から、よく忘れられるコスト項目を二つ(NAT/Egress、Logs retention)選び、本章のどの節がそれぞれをどう減らすかを対にしてみてください。
  2. Fargate compute コストを減らす三つのポイント(Right Sizing / Spot / Graviton)を §2 から整理し、それぞれの危険または前提条件を一行ずつ書いてみてください。100% Spot がなぜ危険かを §「落とし穴 4」と結びつけて説明してみてください。
  3. providerdefault_tags がコスト管理でなぜ核心かを一段落で説明し、第25章 Terraform 入門 のモジュール構造でこのタグがどこに入れば、すべての環境に一貫して適用されるかをメモしておいてください。

一行まとめ: 小さな運用の請求書は Fargate と RDS が半分以上で、NAT/Egress と Logs retention がよく忘れられる。Cost Explorer と Anomaly Detection で漏れを見つけ、Right Sizing / Spot / Graviton / Savings Plans で compute を減らし、Logs・S3・ECR lifecycle と VPC Endpoint で storage と network を減らす。default_tags ですべての資源を分類可能にすれば、開発者本人が自分のコストを意識する FinOps が働く。

次の章 #

4部まで一つのシステムが運用可能な形で集まりました。ここからは5部 運用・セキュリティ・コストへつながります。次の 第28章 VPC 深掘り では、これまで default VPC と簡易セットアップで素早く通り過ぎてきたネットワークを、運用規模で改めて深く設計します — サブネットルーティング、NAT と VPC Endpoint、セキュリティグループと NACL、そしてマルチ AZ ネットワーク構造まで。

X