ECS+FargateのAutoScaling設定をTerraformで定義する(スケジュール編)


はじめに

ECS+Fargate の AutoScaling は便利で、徐々にアクセス量が増えていくようなケースには対応できるものの、一気にトラフィックが3倍になるようなバーストケースは、仮に予見されるものであってもCPUリソースやアクセス量を監視しているだけでは対応しきれない。
そういったケースでは、予めスケジュールを組んでタスク量を調節しておくことで対応をしよう。
※予見できないバーストトラフィックはさすがに無理なので、そこはもうある程度余裕をもってリソースを用意しておくしかないだろう。

本記事では、ベースに前回の記事の予備知識があることを前提とする。ECS+Fargate や AutoScaling に関する基本的な設定は改めて説明はしないので悪しからず。
また、クラスメソッド先生の記事も参考に。

なお、EC2のスケジュールベースの AutoScaling はマネージメントコンソールで確認できるが、ECS+Fargateの場合はどこを見ても確認できない。謎だが、ちゃんと動作はするので気にしないことにした。

スケジュールベースの AutoScaling の Terraform での設定方法

Terraform では appautoscaling_scheduled_action のリソースを使う。

対して難しいことはない。上記の例のように、時間帯でトラフィックが予期できる場合は、以下のように2つのスケジュールを組むことでリソース量をコントロール可能になる。

resource "aws_appautoscaling_scheduled_action" "ecsfargate_peak" {
  name               = "ecsfargate_peak"
  service_namespace  = aws_appautoscaling_target.ecsfargate.service_namespace
  resource_id        = aws_appautoscaling_target.ecsfargate.resource_id
  scalable_dimension = aws_appautoscaling_target.ecsfargate.scalable_dimension
  schedule           = "cron(15 * * * ? *)"

  scalable_target_action {
    min_capacity = 20
    max_capacity = 40
  }
}

resource "aws_appautoscaling_scheduled_action" "ecsfargate_normal" {
  name               = "ecsfargate_normal"
  service_namespace  = aws_appautoscaling_target.ecsfargate.service_namespace
  resource_id        = aws_appautoscaling_target.ecsfargate.resource_id
  scalable_dimension = aws_appautoscaling_target.ecsfargate.scalable_dimension
  schedule           = "cron(20 * * * ? *)"

  scalable_target_action {
    min_capacity = 10
    max_capacity = 20
  }
}

schedule のプロパティは、ユーザーガイドに設定例が書かれている。at で日時指定、rate で間隔で定期的に動作させることができ、cron で毎時何分に起動や、毎日何時何分に起動といったことができる。cronCloudWatch
Event の記載方法
に従う。

上記の例では、毎時15分にピークトラフィックに備えてスケールアウトさせ、毎時20分に収まるのでスケールインする。当然ながらこれは例であって、ECS+Fargate は課金単位が1時間なので、こういった設定をする意味はない。

実際に動作させる

上記の Terraform を apply した後の動作がこちら。

多少のタイムラグはあるものの、16:16 に必要なタスク数が上がってタスク実行され、16:21 には下がって drain されている。
ECSのサービスのログでも、以下のように出力されていて、時間通りにスケジュールでタスク数の最大と最少が変更されていることが分かる。

今回はCPU使用率によるスケールインのポリシーも設定しているため、スケジュールで MAX:4/MIN:2 になった後に、CPU使用率が低いためにタスク数が2まで推移する、といった動作だ。

これで、CPU使用率やトラフィック量だけでなく、時間でより細かくタスク数をコントロールできるようになった!