Skip to content

Amazon Athena コストモニタリング設計書

概要

Amazon Athenaを使用したログ分析におけるコスト高騰リスクを防止するための包括的な監視・制御システムの設計書です。単一クエリの暴走防止から、複数クエリの累積コスト監視まで、多段階防御アプローチでコストガバナンスを実現します。


背景と課題

現状分析

FastDoctorでは、今後各種ログ分析にAthenaを活用する予定ですが、本格運用開始前にコスト管理体制を整備する必要があります。

ログ分析の計画

  • 用途: アプリケーションログ、アクセスログ、監査ログの分析
  • 想定スキャン量: 1TB/日(※あくまで仮の想定値。実際の使用量は運用開始後に判明)
  • 想定月次コスト: $150/月(1TB/日 × $5/TB × 30日)
  • 実行頻度: 過去データの調査が必要になった際にアドホッククエリを実行

想定されるリスク

本格運用開始前に、以下のリスクを想定し、予防的な対策を講じます:

  1. 単一クエリの暴走リスク

    • リスク: SELECT * FROM huge_table などの最適化されていないクエリ
    • 影響: 1クエリで数十GB〜数百GBスキャンの可能性
    • 潜在的損失: 意図しない高額課金($50〜$500/クエリ)
  2. 累積コストの可視化不足

    • リスク: 複数の小規模クエリが累積すると大きなコストに
    • 影響: 日次・月次予算の超過
    • 潜在的損失: 月末に予算オーバーが判明(手遅れ)
  3. リアルタイム監視の欠如

    • リスク: 監視がない状態でクエリを実行
    • 影響: 異常なコスト発生を検知できない
    • 潜在的損失: 数日〜数週間の検知遅延で$100〜$1,000の損失
  4. アラート基盤の未整備

    • リスク: コスト異常時の通知機能なし
    • 影響: 問題の早期発見・対処が困難
    • 潜在的損失: コスト高騰の長期化

本設計の目的

上記リスクを未然に防止するため、以下を実現します:

  1. 単一クエリ暴走防止: Athena Workgroup Controlsによる1クエリあたりのスキャン上限設定
  2. 複数クエリ累積監視: CloudWatch Alarmによる一定期間内の累積スキャン量監視
  3. 即時アラート通知: AWS Chatbot + Slack統合による迅速な問題共有
  4. 長期コスト分析: Cost Explorerベースの週次ワークフローによる自動分析・検知

検証で判明した課題

Datadog監視の技術的課題

当初はDatadog AWS統合による監視を計画していましたが、実装・検証の結果、以下の技術的課題により採用を見送りました。

課題1: スパースメトリクスの補間問題

  • 問題: AthenaのProcessedBytesメトリクスは、クエリ実行時のみデータポイントが送信されるスパースメトリクス(Event-driven metrics)
  • 影響: Datadogはスパースメトリクスの欠損データポイントを「前回の値」で補間するため、ALERT状態が自動的にリカバリしない
  • 検証結果: アラート発生後、クエリが実行されない期間でもALERT状態が継続し、自動リカバリが実現できなかった

課題2: 補間関数による改善の失敗 複数の補間関数を試行しましたが、いずれも自動リカバリを実現できませんでした:

試行した関数期待した動作実際の結果判定
.as_count()カウント型として扱い補間を抑制ALERT状態が継続❌ 失敗
.fill(zero)欠損データを0で埋めるALERT状態が継続❌ 失敗
.fill(null)欠損データをnullとして扱うALERT状態が継続❌ 失敗
default_zero()デフォルト値を0に設定ALERT状態が継続❌ 失敗

課題3: Datadogのアーキテクチャ制約

  • Datadogは独自のメトリクスストレージを使用し、CloudWatchメトリクスをポーリングして取得
  • スパースメトリクスの補間ロジックは、Datadog側で固定されており、ユーザー側で制御不可
  • この設計により、イベント駆動型のメトリクスに対する自動リカバリが技術的に困難

CloudWatch Alarm採用の理由

上記課題を解決するため、CloudWatch Alarm + AWS Chatbot方式を採用しました。

CloudWatch Alarmの利点:

  1. スパースメトリクス対応設定

    • treat_missing_data = "notBreaching": 欠損データを「閾値違反なし」として扱う
    • この設定により、クエリが実行されない期間は自動的にOK状態にリカバリ
  2. ネイティブ統合

    • AthenaメトリクスはCloudWatch内で完結
    • 外部システムへのメトリクス転送・補間処理が不要
    • データポイントの遅延や欠損リスクを最小化
  3. AWS Chatbotによるリアルタイム通知

    • SNS Topic経由でSlackへ即時通知
    • アラーム発生とリカバリの両方を通知
    • 既存のAWS Health Event通知基盤を活用

検証結果:

  • ✅ アラート発生: 閾値超過時に即座にSlack通知
  • ✅ 自動リカバリ: クエリ停止後、次の評価期間で自動的にOK状態に復帰
  • ✅ 手動テスト: aws cloudwatch set-alarm-stateによる動作確認完了
  • ✅ 実データテスト: 実際のクエリ実行(292バイトスキャン)による通知確認完了

要件定義

機能要件

  • FR-1: 単一クエリのスキャン量を物理的に制限(Workgroup Controls)
  • FR-2: 短時間(10分)での累積スキャン量を監視(CloudWatch Alarm)
  • FR-3: 段階的なアラート通知(Warning/Critical)
  • FR-4: Slackへの即時通知(AWS Chatbot経由)
  • FR-5: スパースメトリクスに対する自動リカバリ機能

非機能要件

  • NFR-1: 実装負荷が低い(1日以内で構築可能)
  • NFR-2: 管理が簡単(運用負荷最小)
  • NFR-3: 監視システム自体のコストが低い(CloudWatch無料枠内)
  • NFR-4: 検知遅延が短い(評価期間: 10分、カスタマイズ可能)
  • NFR-5: 通知が確実(AWS Chatbot + Slack統合)
  • NFR-6: スパースメトリクスに対応した自動リカバリ

アーキテクチャ設計

全体アーキテクチャ

通知先Slackチャンネル:

  • infra-dev / staging環境: #squad-sre-noti-saas-status-dev
  • production環境: #squad-sre-noti-saas-status

監視の仕組み

Layer 1: 単一クエリ暴走防止(Athena Workgroup Controls)

目的: 1クエリあたりのスキャン上限を設定し、コスト高騰を物理的に防止

特徴:

  • ✅ 検知速度: 瞬時(<1秒)
  • ✅ コスト: $0
  • ✅ 確実性: 100%(物理的にブロック)
  • ✅ 設定項目: bytes_scanned_cutoff_per_query = 10GB

Layer 2: スキャン量監視(CloudWatch Alarm + AWS Chatbot)

目的: 一定期間内の複数クエリによる累積スキャン量を監視し、コスト高騰を早期検知

特徴:

  • ✅ Athena WorkgroupがCloudWatchにメトリクスを送信(publish_cloudwatch_metrics_enabled = true
  • ✅ CloudWatch Alarmが直接メトリクスを評価(外部システム不要)
  • ✅ スパースメトリクス対応: treat_missing_data = "notBreaching"により自動リカバリを実現
  • ✅ 監視間隔: デフォルト10分(evaluation_period_seconds変数でカスタマイズ可能)
  • ✅ 追加コストなし: CloudWatch Alarm無料枠内(10アラーム/月まで無料)

AWS Chatbot統合の制約と対応

AWS Chatbotの制限:

  • 1つのSlackチャンネルには、1つのAWS Chatbot設定しか紐付けられない(AWSアカウント単位)
  • 複数のSNS TopicをSlackに通知したい場合、Chatbot設定を共有する必要がある

実装上の対応: 本システムでは、既存のAWS Health Event用Chatbot設定を活用し、Athena監視用SNS TopicをChatbot設定に追加する方式を採用しました。

hcl
# globals/aws-health-event/main.tf
module "aws-health-event" {
  source = "../../../../template_modules/common/platform/aws-health-event"

  # 既存のAWS Health Event SNS Topic + Athena監視SNS Topicを統合
  additional_sns_topic_arns = [
    data.terraform_remote_state.common.outputs.athena_cost_monitoring_sns_topic_arn
  ]
}

通知先Slackチャンネル: #squad-sre-noti-saas-status-dev

  • AWS Health Event通知(本来の用途)
  • Athena Cost Monitoring通知(追加)

Layer 3: 長期コスト分析(Cost Explorer週次ワークフロー)

目的: 週次コスト傾向分析と異常検知

  • 実行頻度: 週次(毎週月曜日)
  • 分析内容: Cost Explorerを使用したAthenaコスト傾向分析
  • 検知方法: 前週比での異常増加の自動検知
  • 通知先: Slack(#sre-alerts)
  • 用途: 中長期的なコスト傾向把握と異常の早期発見

コスト試算

前提条件

  • 想定スキャン量: 1TB/日(※あくまで仮の想定値)
  • Athena料金: $5/TB
  • 月次稼働日: 30日

注記: 以下のシナリオで使用するスキャン量および削減幅は、あくまでも削減効果のイメージを示すための仮の数値です。実際の運用では、クエリパターンやデータ量に応じて適宜調整が必要です。

シナリオ別コスト試算

シナリオ1: 監視なし(リスクケース)

項目日次月次年次
Athenaスキャン料金$5.00$150.00$1,800.00
S3(クエリ結果)$0.01$0.30$3.60
合計$5.01$150.30$1,803.60

リスク:

  • ❌ 暴走クエリで突然10TB → $50/日の可能性
  • ❌ 異常検知なし
  • ❌ 年間潜在的損失リスク: $500〜$5,000

シナリオ2: Workgroup Controls のみ

設定: bytes_scanned_cutoff_per_query = 10GB

想定される効果:

  • 暴走クエリが自動キャンセル(推定2-3件/日)
  • 平均スキャン量: 1TB → 0.85TB(15%削減
項目日次月次年次削減額
Athenaスキャン料金$4.25$127.50$1,530.00-$270/年
S3 クエリ結果$0.01$0.25$3.00-$0.60/年
Workgroup Controls$0.00$0.00$0.00無料
合計$4.26$127.75$1,533.00-$270.60/年

効果:

  • ✅ 年間約$270節約(15%削減)
  • ✅ 追加コストゼロ
  • ✅ 暴走クエリ自動防止

シナリオ3: 推奨構成(Workgroup + CloudWatch Alarm監視)

設定:

  • Workgroup Controls: 10GB/クエリ
  • CloudWatch Alarm(Warning): 50GB/評価期間
  • CloudWatch Alarm(Critical): 100GB/評価期間
  • 評価期間: 10分(カスタマイズ可能)
項目日次月次年次
Athenaスキャン料金$4.25$127.50$1,530.00
S3 クエリ結果$0.01$0.25$3.00
CloudWatch Alarm監視$0.00$0.00*$0.00*
合計$4.26$127.75$1,533.00

*CloudWatch Alarm無料枠内(10アラーム/月まで無料)

投資対効果(ROI):

年間コスト削減: $270.60
年間追加コスト: $0(CloudWatch無料枠内)
純利益: $270.60/年(15%削減)

ROI = ∞(追加コストゼロ)

効果:

  • ✅ 年間約$270節約
  • ✅ 事前警告あり(評価期間ごと、デフォルト10分)
  • ✅ 暴走クエリ自動防止
  • ✅ Slack通知で即座に対応可能(AWS Chatbot経由)
  • ✅ 自動リカバリ機能(運用負荷削減)
  • ✅ 追加コスト: $0(CloudWatch無料枠内)

30分間でのスキャン量シミュレーション

Athenaの制限値

  • 同時実行クエリ数: 20(デフォルト)
  • 1クエリの上限: 10GB(Workgroup設定)
  • クエリ実行時間: 30秒〜2分(平均1分)

最悪ケースシナリオ

シナリオクエリペース30分のクエリ数スキャン量コスト
通常1クエリ/分30300GB$1.50
高速1クエリ/30秒60600GB$3.00
最悪同時20クエリ連続1,20012TB$60 🚨

結論: 日次監視(24時間間隔)では、最悪ケースで$2,880の損失リスクあり。 対策: 10分間隔の監視が必須(運用しながら調整)


監視戦略

監視間隔の決定

監視間隔ごとの検知能力

監視間隔最悪ケース累積通常ケース累積検知遅延最大損失推奨度
5分2TB ($10)50GB ($0.25)最大5分$10⭐⭐⭐⭐
10分4TB ($20)100GB ($0.50)最大10分$20⭐⭐⭐⭐⭐
15分6TB ($30)150GB ($0.75)最大15分$30⭐⭐⭐⭐
30分12TB ($60)300GB ($1.50)最大30分$60⭐⭐⭐
1時間24TB ($120)600GB ($3.00)最大1時間$120⭐⭐
24時間576TB ($2,880)14.4TB ($72)最大24時間$2,880

推奨: 10分間隔(評価期間は変数でカスタマイズ可能)

選定理由:

  1. ✅ 検知遅延が短い(最大10分)
  2. ✅ 最大損失が許容範囲内($20)
  3. ✅ CloudWatch Alarm設定が簡単
  4. ✅ 誤検知が少ない(適度な集計期間)
  5. ✅ 運用負荷が低い
  6. ✅ 実運用で閾値・評価期間を調整可能(evaluation_period_seconds変数)

評価期間のカスタマイズ:

hcl
# 5分評価の場合
evaluation_period_seconds = 300

# 10分評価の場合(デフォルト)
evaluation_period_seconds = 600

# 30分評価の場合
evaluation_period_seconds = 1800

# 1時間評価の場合
evaluation_period_seconds = 3600

多段階アラート設定

予算ベースの閾値設定

月予算: $150
日予算: $5.00
時間予算: $0.208(≈ $0.20)
10分予算: $0.035(≈ $0.04)

Layer 1: Workgroup Controls(物理的ブロック)

目的: 単一クエリの暴走防止
方式: 上限到達で自動キャンセル
閾値: 10GB/クエリ($0.05)
検知: 瞬時(<1秒)
通知: なし(物理的にブロックのみ)

Layer 2: CloudWatch Alarm(10分累積監視)

レベル閾値コスト日次換算月次換算アクション自動リカバリ
Warning50GB/10分$0.25$36/日$1,080/月Slack通知✅ 自動
Critical100GB/10分$0.50$72/日$2,160/月Slack(緊急)✅ 自動

:

  • 閾値は運用開始後に実際のスキャン量に基づいて調整します
  • 評価期間(デフォルト10分)はevaluation_period_seconds変数で変更可能
  • スパースメトリクス対応により、クエリが実行されない期間は自動的にOK状態に復帰

CloudWatch Alarmの設定:

hcl
# Warning Alarm設定
alarm_name                = "[Athena][infra-dev][All Workgroups] 10分累積 Warning"
metric_name               = "ProcessedBytes"
namespace                 = "AWS/Athena"
statistic                 = "Sum"
period                    = 600  # 10分
evaluation_periods        = 1
threshold                 = 53687091200  # 50GB
comparison_operator       = "GreaterThanThreshold"
treat_missing_data        = "notBreaching"  # 自動リカバリの要

アラート通知メッセージ(AWS Chatbot経由): AWS Chatbotが自動的にSlackに以下の情報を通知します:

  • アラーム名
  • 現在の状態(ALARM/OK)
  • メトリクス値
  • 閾値
  • トリガー時刻
  • AWS Console リンク

技術仕様

AWS実装(Workgroup)

📄 Terraform実装例を表示(クリックして展開)

注意: 以下は実装例です。実際の環境に合わせて調整してください。

1. Athena Workgroup

hcl
# ============================================================================
# 実装例: Athena Workgroup
# ============================================================================
resource "aws_athena_workgroup" "log_analysis" {
  name        = "log-analysis-workgroup"
  description = "Log analysis workgroup with cost controls"
  state       = "ENABLED"

  configuration {
    # ========================================
    # CloudWatch メトリクス送信(Datadog監視に必須)
    # ========================================
    publish_cloudwatch_metrics_enabled = true

    # ========================================
    # コスト制御: 10GB/クエリ
    # ========================================
    bytes_scanned_cutoff_per_query = 10737418240  # 10GB

    # ========================================
    # クエリ結果の保存先
    # ========================================
    result_configuration {
      output_location = "s3://${var.athena_results_bucket}/results/"

      encryption_configuration {
        encryption_option = "SSE_S3"
      }
    }
  }

  tags = {
    Name        = "log-analysis-workgroup"
    ManagedBy   = "Terraform"
    Service     = "log-analysis"
    CostControl = "enabled"
  }
}

CloudWatch Alarm実装

ディレクトリ構成

terraform_for_aws/
├── fastdoctor-template/
│   ├── common/
│   │   └── infra-dev/
│   │       ├── main.tf                      # Athena監視モジュール呼び出し
│   │       ├── variable.tf                  # 環境固有変数の宣言
│   │       ├── outputs.tf                   # SNS Topic ARN出力
│   │       └── globals/
│   │           └── aws-health-event/
│   │               └── main.tf              # Chatbot統合設定
│   └── template_modules/
│       └── options/
│           └── athena-cost-monitoring/      # 再利用可能モジュール
│               ├── main.tf                  # CloudWatch Alarm定義
│               ├── variables.tf             # モジュール変数
│               ├── outputs.tf               # SNS Topic ARN等
│               └── README.md                # 使用方法ドキュメント

モジュール実装

全Workgroup監視機能: workgroup_name = nullとすることで、特定のWorkgroupではなく全てのWorkgroupを集約して監視できます。これにより、予期しないWorkgroup作成によるコスト高騰を防止できます。

📄 CloudWatch Alarm Terraform実装例を表示(クリックして展開)

注意: 以下は実装例です。実際の環境に合わせて調整してください。

fastdoctor-template/template_modules/options/athena-cost-monitoring/main.tf
hcl
# ============================================================================
# 実装例: CloudWatch Alarm - 累積スキャン量監視
# ============================================================================

# ============================================================================
# Workgroup監視の柔軟性
# ============================================================================
# - workgroup_name = null → 全Workgroupを監視(推奨)
# - workgroup_name = "specific-name" → 特定Workgroupのみ監視

locals {
  # 全Workgroup監視かどうかを判定
  monitor_all_workgroups = var.workgroup_name == null || var.workgroup_name == ""

  # CloudWatch Dimensions: 全Workgroup監視時は集約ディメンションを使用
  dimensions = local.monitor_all_workgroups ? {
    QueryState = "SUCCEEDED"
    QueryType  = "DML"
  } : {
    WorkGroup = var.workgroup_name
  }

  # アラーム名のサフィックス
  alarm_name_suffix = local.monitor_all_workgroups ? "All Workgroups" : var.workgroup_name
}

# ============================================================================
# SNS Topic(アラート通知先)
# ============================================================================
resource "aws_sns_topic" "athena_alerts" {
  name = "${var.project}-athena-alerts-${var.environment}"

  tags = {
    Name        = "${var.project}-athena-alerts-${var.environment}"
    Environment = var.environment
    Service     = "athena-monitoring"
    ManagedBy   = "Terraform"
  }
}

# ============================================================================
# Warning Alarm: 50GB/評価期間
# ============================================================================
resource "aws_cloudwatch_metric_alarm" "athena_10min_warning" {
  count = var.enable_warning_alarm ? 1 : 0

  alarm_name          = "[Athena][${var.environment}][${local.alarm_name_suffix}] 10分累積 Warning"
  alarm_description   = "Athena data scan warning: ${var.threshold_10min_warning_bytes} bytes in ${var.evaluation_period_seconds} seconds"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = 1
  metric_name         = "ProcessedBytes"
  namespace           = "AWS/Athena"
  period              = var.evaluation_period_seconds
  statistic           = "Sum"
  threshold           = var.threshold_10min_warning_bytes
  treat_missing_data  = "notBreaching"  # スパースメトリクス対応: 自動リカバリの要

  dimensions = local.dimensions

  alarm_actions = [aws_sns_topic.athena_alerts.arn]
  ok_actions    = [aws_sns_topic.athena_alerts.arn]

  tags = {
    Name        = "athena-warning-alarm"
    Environment = var.environment
    Severity    = "warning"
    Service     = "athena-monitoring"
    ManagedBy   = "Terraform"
  }
}

# ============================================================================
# Critical Alarm: 100GB/評価期間
# ============================================================================
resource "aws_cloudwatch_metric_alarm" "athena_10min_critical" {
  alarm_name          = "[Athena][${var.environment}][${local.alarm_name_suffix}] 10分累積 Critical"
  alarm_description   = "Athena data scan critical: ${var.threshold_10min_critical_bytes} bytes in ${var.evaluation_period_seconds} seconds"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = 1
  metric_name         = "ProcessedBytes"
  namespace           = "AWS/Athena"
  period              = var.evaluation_period_seconds
  statistic           = "Sum"
  threshold           = var.threshold_10min_critical_bytes
  treat_missing_data  = "notBreaching"  # スパースメトリクス対応: 自動リカバリの要

  dimensions = local.dimensions

  alarm_actions = [aws_sns_topic.athena_alerts.arn]
  ok_actions    = [aws_sns_topic.athena_alerts.arn]

  tags = {
    Name        = "athena-critical-alarm"
    Environment = var.environment
    Severity    = "critical"
    Service     = "athena-monitoring"
    ManagedBy   = "Terraform"
  }
}

実装のポイント:

  1. スパースメトリクス対応

    • treat_missing_data = "notBreaching": クエリが実行されない期間は自動的にOK状態に復帰
    • これにより、Datadogで実現できなかった自動リカバリを実現
  2. 全Workgroup監視

    • workgroup_name = null時: QueryState=SUCCEEDED + QueryType=DMLディメンションで全Workgroupを集約監視
    • 予期しないWorkgroup作成によるコスト高騰を防止
  3. 評価期間のカスタマイズ

    • evaluation_period_seconds変数でperiodを変更可能(デフォルト: 600秒=10分)
    • 環境やユースケースに応じて柔軟に調整
  4. SNS Topicの統合

    • モジュール内でSNS Topicを作成
    • outputでARNを公開し、AWS Chatbot統合で使用
fastdoctor-template/template_modules/options/athena-cost-monitoring/variables.tf
hcl
# ============================================================================
# 実装例: 変数定義
# ============================================================================

# ============================================================================
# 基本設定
# ============================================================================
variable "project" {
  type        = string
  description = "Project name"
}

variable "environment" {
  type        = string
  description = "Environment name (infra-dev, develop, staging, production)"
}

variable "workgroup_name" {
  type        = string
  description = "Athena Workgroup name to monitor. Set to null or empty string to monitor all workgroups."
  default     = null
}

# ============================================================================
# 監視期間設定
# ============================================================================
variable "evaluation_period_seconds" {
  type        = number
  description = "CloudWatch Alarm evaluation period in seconds. Default: 600 (10 minutes)"
  default     = 600
}

# ============================================================================
# 閾値設定
# ============================================================================
variable "threshold_10min_warning_bytes" {
  type        = number
  description = "Warning threshold for data scan (bytes). Default: 50GB"
  default     = 53687091200  # 50GB = 50 * 1024^3
}

variable "threshold_10min_critical_bytes" {
  type        = number
  description = "Critical threshold for data scan (bytes). Default: 100GB"
  default     = 107374182400  # 100GB = 100 * 1024^3
}

# ============================================================================
# オプション設定
# ============================================================================
variable "enable_warning_alarm" {
  type        = bool
  description = "Enable warning level alarm. Set to false to use only critical alarm."
  default     = true
}

環境別定義例

📄 環境別定義例を表示(クリックして展開)

注意: 以下は実装例です。実際の環境に合わせて調整してください。

fastdoctor-template/common/infra-dev/main.tf
hcl
# ============================================================================
# 実装例: infra-dev環境のAthenaコスト監視(全Workgroup監視)
# ============================================================================

module "athena-cost-monitoring" {
  source = "../../template_modules/options/athena-cost-monitoring"

  project        = var.project
  environment    = var.athena_monitoring_environment
  workgroup_name = null  # 全Workgroupを監視(推奨)

  # 閾値設定
  threshold_10min_warning_bytes  = var.athena_monitoring_threshold_warning_bytes
  threshold_10min_critical_bytes = var.athena_monitoring_threshold_critical_bytes

  # 評価期間(デフォルト: 600秒 = 10分)
  evaluation_period_seconds = 600

  # Warning Alarmを有効化
  enable_warning_alarm = true

  providers = {
    aws = aws.tokyo
  }
}
fastdoctor-template/common/infra-dev/variable.tf
hcl
# Athena監視の環境変数
variable "athena_monitoring_environment" {
  type        = string
  description = "Environment name for Athena cost monitoring"
}

variable "athena_monitoring_threshold_warning_bytes" {
  type        = number
  description = "Warning threshold for Athena data scan (bytes)"
}

variable "athena_monitoring_threshold_critical_bytes" {
  type        = number
  description = "Critical threshold for Athena data scan (bytes)"
}
fastdoctor-template/common/infra-dev/terraform.tfvars(S3で管理)
hcl
# Athena監視設定
athena_monitoring_environment                = "infra-dev"
athena_monitoring_threshold_warning_bytes    = 53687091200   # 50GB
athena_monitoring_threshold_critical_bytes   = 107374182400  # 100GB
fastdoctor-template/common/infra-dev/globals/aws-health-event/main.tf(Chatbot統合)
hcl
# ============================================================================
# AWS Health EventとAthena Cost MonitoringのChatbot統合
# ============================================================================
# 注意: AWS Chatbotの制限により、1つのSlackチャンネルには1つのChatbot設定しか
#       紐付けられないため、AWS Health EventとAthena Cost Monitoringの通知を
#       このChatbot設定に統合しています。

data "terraform_remote_state" "common" {
  backend = "s3"
  config = {
    bucket = "fd-tfstate-infra-dev"
    key    = "common.tfstate"
    region = "ap-northeast-1"
  }
}

module "aws-health-event" {
  source = "../../../../template_modules/common/platform/aws-health-event"

  chatbot_role_name   = var.chatbot_role_name
  chatbot_policy_name = var.chatbot_policy_name
  channel_name        = var.channel_name
  slack_workspace_id  = var.slack_workspace_id
  slack_channel_id    = var.slack_channel_id
  sns_topic_name      = var.sns_topic_name
  event_rule_name     = var.event_rule_name

  # Athena Cost Monitoring SNS Topicを追加
  additional_sns_topic_arns = [
    data.terraform_remote_state.common.outputs.athena_cost_monitoring_sns_topic_arn
  ]
}

運用ガイド

アラート対応フロー

Level 1: Query Cancelled(瞬間値)

トリガー: 単一クエリが10GBを超過してキャンセル

対応手順:

  1. クエリの確認

    bash
    aws athena get-query-execution --query-execution-id <query-id>
  2. クエリの最適化検討

    • パーティション使用の確認
    • WHERE句の最適化
    • 不要なカラムの除外
  3. 必要に応じてWorkgroup変更

    • 正当に10GB超が必要な場合、大規模クエリ用Workgroupを検討

Level 2: CloudWatch Alarm - Warning(50GB超過)

トリガー: 評価期間(デフォルト10分)で50GB以上スキャン

Slack通知内容(AWS Chatbot経由):

  • アラーム名: [Athena][infra-dev][All Workgroups] 10分累積 Warning
  • 状態: ALARM
  • メトリクス値: 実際のスキャン量(バイト)
  • 閾値: 53687091200 bytes (50GB)
  • AWS Consoleリンク

対応手順:

  1. CloudWatch Consoleで詳細確認

    • AWS Consoleリンクから直接アクセス
    • メトリクスの推移を確認
    • スパイクか継続的な増加かを判断
  2. AWS CLIで実行クエリ確認

    bash
    # 最近実行されたクエリをリスト表示
    aws athena list-query-executions \
      --max-results 50 \
      --region ap-northeast-1
  3. 頻繁に実行されているクエリの特定

    bash
    # クエリ詳細を確認
    aws athena get-query-execution \
      --query-execution-id <query-id> \
      --region ap-northeast-1
  4. 一時的な高負荷か継続的な問題かを判断

    • 一時的: 監視継続(自動リカバリを待つ)
    • 継続的: Level 3へエスカレーション

Level 3: CloudWatch Alarm - Critical(100GB超過)

トリガー: 評価期間(デフォルト10分)で100GB以上スキャン

Slack通知内容(AWS Chatbot経由):

  • アラーム名: [Athena][infra-dev][All Workgroups] 10分累積 Critical
  • 状態: ALARM
  • メトリクス値: 実際のスキャン量(バイト)
  • 閾値: 107374182400 bytes (100GB)
  • AWS Consoleリンク

対応手順:

  1. 即座に実行中クエリの確認

    bash
    aws athena list-query-executions \
      --status-filter RUNNING \
      --region ap-northeast-1
  2. 必要に応じてクエリ強制停止

    bash
    aws athena stop-query-execution \
      --query-execution-id <query-id> \
      --region ap-northeast-1
  3. 根本原因の調査

    • 自動化ジョブの暴走
    • スクリプトのバグ
    • 意図しない全件スキャン
    • 予期しないWorkgroupの作成
  4. 一時的な対策

    • 問題のクエリを停止
    • 必要に応じてWorkgroup一時停止も検討
    • IAM権限の一時的制限

アラート自動リカバリ

重要: CloudWatch Alarmはtreat_missing_data = "notBreaching"設定により、クエリが実行されない期間(データポイントなし)は自動的にOK状態に復帰します。

リカバリ通知(AWS Chatbot経由):

  • アラーム名: [Athena][infra-dev][All Workgroups] 10分累積 Warning/Critical
  • 状態: OK
  • メッセージ: アラームが復旧したことを通知

確認事項:

  • リカバリ通知を受信したら、Slack上で確認完了を報告
  • 必要に応じてインシデント事後分析(Post-mortem)を実施

セキュリティ考慮事項

IAMポリシー

📄 IAMポリシー例を表示(クリックして展開)

注意: 以下は実装例です。実際の環境に合わせて調整してください。

Athena実行権限

hcl
data "aws_iam_policy_document" "athena_user" {
  # Athena実行権限
  statement {
    effect = "Allow"
    actions = [
      "athena:StartQueryExecution",
      "athena:GetQueryExecution",
      "athena:GetQueryResults",
      "athena:StopQueryExecution",
      "athena:GetWorkGroup",
      "athena:ListQueryExecutions",
    ]
    resources = [
      aws_athena_workgroup.log_analysis.arn,
    ]
  }

  # S3アクセス権限
  statement {
    effect = "Allow"
    actions = [
      "s3:GetObject",
      "s3:ListBucket",
    ]
    resources = [
      "arn:aws:s3:::${var.log_bucket_name}/*",
      "arn:aws:s3:::${var.log_bucket_name}",
    ]
  }

  # クエリ結果保存権限
  statement {
    effect = "Allow"
    actions = [
      "s3:PutObject",
      "s3:GetObject",
    ]
    resources = [
      "arn:aws:s3:::${var.athena_results_bucket}/results/*",
    ]
  }

  # Glue Data Catalog権限
  statement {
    effect = "Allow"
    actions = [
      "glue:GetDatabase",
      "glue:GetTable",
      "glue:GetPartitions",
    ]
    resources = ["*"]
  }
}

導入ロードマップ

Phase 1: AWS基盤構築

実装内容:

  • ✅ Athena Workgroup作成
  • ✅ Data Usage Controls設定(10GB/クエリ)

成果物:

  • Workgroup設定完了
  • 単一クエリ暴走防止機能有効化

Phase 2: CloudWatch Alarm監視構築(infra-dev検証完了)

実装内容:

  • ✅ CloudWatch Alarmモジュール作成(template_modules/options/athena-cost-monitoring
  • ✅ 10分累積監視設定(Warning: 50GB / Critical: 100GB)
  • ✅ スパースメトリクス対応(treat_missing_data = "notBreaching"
  • ✅ 全Workgroup監視機能実装
  • ✅ 評価期間のカスタマイズ機能(evaluation_period_seconds変数)
  • ✅ AWS Chatbot統合(既存AWS Health Event設定を活用)
  • ✅ Slack通知設定(#squad-sre-noti-saas-status-dev: infra-dev/staging用)

成果物:

  • ✅ infra-dev環境でのCloudWatch Alarm構築完了
  • ✅ Slack通知機能有効化・検証完了
  • ✅ 自動リカバリ機能検証完了
  • ✅ 実データテスト完了(292バイトスキャンクエリ)
  • ✅ 手動アラームテスト完了(set-alarm-state

検証結果(infra-dev環境):

  • アラート発生: ✅ 成功(Slack #squad-sre-noti-saas-status-dev 通知確認)
  • 自動リカバリ: ✅ 成功(OK状態への自動復帰確認)

次のステップ:

  • staging環境への展開
  • production環境への展開(通知先: #squad-sre-noti-saas-status)

Phase 3: 運用最適化(継続)

実装内容:

  • ✅ Cost Explorer週次ワークフロー統合
  • ✅ チーム向けトレーニング
  • ✅ 閾値チューニング

KPI:

  • 平均スキャン量: 実測値をベースに最適化
  • アラート対応時間: 10分以内
  • 週次コスト傾向: 異常増加の早期検知

まとめ

期待効果

項目リスクケース導入後改善
月次コスト$150.30$127.75-15%
検知遅延なし10分(カスタマイズ可)早期検知
最大損失リスク無制限$20(10分)制御可能
運用工数-+1時間/月微増
監視システムコスト$0$0無料
自動リカバリなし✅ 自動運用負荷削減

*CloudWatch Alarm無料枠内(10アラーム/月まで無料)

主要な利点

  1. リスク予防

    • 運用開始前にコスト制御機能を整備
    • 単一クエリ暴走防止: 物理的ブロック(Workgroup Controls)
    • 累積コスト監視: 評価期間(デフォルト10分)で早期検知
    • 全Workgroup監視: 予期しないWorkgroup作成によるコスト高騰を防止
  2. コスト最適化

    • データドリブンな意思決定
    • CloudWatch Metricsでコスト傾向の可視化
    • カスタマイズ可能な評価期間(5分〜1時間)
    • 追加コストゼロ(CloudWatch無料枠内)
  3. 運用効率化

    • 自動監視・通知(CloudWatch Alarm + AWS Chatbot)
    • 問題の早期発見(評価期間内)
    • 自動リカバリ: クエリ停止後、自動的にOK状態に復帰
    • Slack統合で迅速な対応
    • 運用負荷削減(手動リカバリ不要)
  4. 技術的優位性

    • スパースメトリクス対応(Datadogで実現できなかった自動リカバリ)
    • ネイティブAWS統合(外部システム依存なし)
    • 柔軟な設定(評価期間・閾値・Workgroup範囲)
    • Terraform化による再現性・移植性

参考資料

AWS公式ドキュメント

Terraform Provider

内部ドキュメント

  • Athena Cost Monitoring Module README: fastdoctor-template/template_modules/options/athena-cost-monitoring/README.md
  • Athena Cost Monitoring Datadog Verification: docs/aws/service-guides/athena-datadog-verification.md(未作成)
  • Datadog Setup Documentation: datadog/common/infra-dev/ATHENA_MONITOR_SETUP.md(未作成)

改訂履歴

バージョン日付作成者変更内容
1.02026-02-17SREチーム初版作成