🎰

【Terraform】通常デプロイとスロットリング発生時の閾値チューニング

2024/05/22に公開

現状のコード

resource "aws_cloudwatch_metric_alarm" "ecs_throttling_alarm" {
  alarm_name          = "${var.service}-${var.environment}-ecs-throttling-alarm"
  comparison_operator = "GreaterThanOrEqualToThreshold"
  evaluation_periods  = 1 # 1回の評価でアラームを発生
  metric_name         = "PendingTaskCount"
  namespace           = "ECS/ContainerInsights"
  period              = 60 # 1分ごとに監視
  statistic           = "Sum"
  threshold           = 1 # 1タスク以上がPending状態ならアラーム
  datapoints_to_alarm = 1 # 1データポイントが閾値を超えたらアラーム
  alarm_description   = "コードのバグによるコンテナの起動失敗が原因で、ECSのPendingTaskCountが設定された閾値を超えた場合にアラームが発生します"
  actions_enabled     = true
  alarm_actions       = [aws_sns_topic.ecs_throttling_notifications.arn]
  treat_missing_data  = "notBreaching" # データがない場合は正常として扱う
  dimensions = {
    ClusterName = "${var.service}-${var.environment}"
    ServiceName = "${var.service}-${var.environment}-app"
  }
}

現状の閾値の説明

この設定では、1分以内にPending状態のタスクが1つでも発生するとすぐにアラームが発火することになります。(動作確認のため閾値を最低限まで下げていました)

evaluation_periods: 1

1回の評価でアラームが発生します。

period: 60

60秒(1分)ごとにメトリクスを監視します。

threshold: 1

Pending状態のタスクが1つ以上になるとアラームが発火します。

datapoints_to_alarm: 1

1回のデータポイントが閾値を超えるとアラームが発火します。

課題

  • 誤検知: 通常のデプロイメント時に一時的に発生するPending状態のタスクでもアラームが発生してしまうため、余分なアラートが飛んでしまいます。

  • 適切な閾値の設定: 通常のデプロイメントと異常な状況を区別するための閾値が適切に設定されていないため、アラートの発砲条件を調整する必要があります。

要件の整理

通常のデプロイメントにかかる時間を測定

通常のデプロイメントと(スロットリングを引き起こす)異常なデプロイメントを双方実行する

正常なデプロイとは

developブランチをデリバリ

異常なデプロイとは

こちらの故意にスロットリングを引き起こせるブランチをデリバリ

https://zenn.dev/take_tech/articles/3d78cc10eda047

具体的な方針の手順

  1. 通常のデプロイメントを実行
  2. 通常のデプロイメントの時間を計測(大体4分前後)
  3. 上記2番を上回る時間のメトリクスに修正(5分間に設定)
  4. 変更をpush
  5. terraform apply
  6. 異常なデプロイメントを引き起こす
  7. アラートが発火される
  8. しばらくしたら、通常のデプロイメントを実行する
  9. この時にアラートが出なければOK

閾値のチューニング

連続する5分間にわたり毎分Pending状態のタスクが5つ以上存在するときにアラートが発生

period: 60

1分間隔でメトリクスの状態を取得

evaluation_periods: 5

5回連続でメトリクスを評価します。これは、1分ごとの評価を5回連続で行うことを意味します。総評価時間は5分です。

threshold: 5

メトリクスの値が5以上であることが条件です。具体的には、Pending状態のタスクが5つ以上であることを意味します。

datapoints_to_alarm: 5

5データポイントが閾値を超えたらアラームが発火します。つまり、5回の評価期間すべてで閾値を超えた場合にアラームが発火されます。

resource "aws_cloudwatch_metric_alarm" "ecs_throttling_alarm" {
  alarm_name          = "${var.service}-${var.environment}-ecs-throttling-alarm"
  comparison_operator = "GreaterThanOrEqualToThreshold"
  evaluation_periods  = 5 # 5回の評価でアラームを発生
  metric_name         = "PendingTaskCount"
  namespace           = "ECS/ContainerInsights"
  period              = 60 # 1分ごとに監視
  statistic           = "Sum"
  threshold           = 5 # 2タスク以上がPending状態ならアラーム
  datapoints_to_alarm = 5 # 1データポイントが閾値を超えたらアラーム
  alarm_description   = "コードのバグによるコンテナの起動失敗が原因で、ECSのPendingTaskCountが設定された閾値を超えた場合にアラームが発生します"
  actions_enabled     = true
  alarm_actions       = [aws_sns_topic.ecs_throttling_notifications.arn]
  treat_missing_data  = "notBreaching" # データがない場合は正常として扱う
  dimensions = {
    ClusterName = "${var.service}-${var.environment}"
    ServiceName = "${var.service}-${var.environment}-app"
  }
}

Discussion