ECS Fargateでスケジュールされたオートスケーリングの設定方法

ECS Fargateでスケジュールされたオートスケーリングの設定方法の表紙画像

ECS Fargateでスケジュールされたオートスケーリングの設定をしようとして、ちょっと迷っていますか?

私も数日前までそんな気持ちでした。セットアップするのに苦労しました。残念ながら、オンラインで見つけたドキュメントや例はあまり役に立ちませんでした。だから、解決方法を見つけたら、Terraformを使った実際のコードの例を共有することにしました。

同じページで話をするために、この投稿では、あなたが何をしているのか知っているものと仮定していますし、その上でオートスケーリングの様々な方法があることも承知しています。今回は、プロジェクトにとって最善ではないかもしれないスケジュールされたオートスケーリングの設定方法を見ていきます。

スケジュールされたオートスケーリングとは、特定の時間にコンピューティングリソースの数を自動的に増減させることを意味します。

私の主な目的はコスト最適化です。最近、AWS Activate for Startupsから提供された$10,000のクレジットを使い切り、請求書で最も高かったのはECSクラスターでした。それについて興味があれば、もう一つブログを書いていますので、その物語をもっと詳しく説明します。

おしゃべりはここまでにして、Terraformのコード例を見てみましょう。

オートスケーリングに必要なリソースを一つ一つ紹介します。

01. オートスケーリングターゲットを作成する

ECSのオートスケーリングを設定する場合、オートスケーリングターゲットはECSサービスです。例えば:

# autoscaling.tf

resource "aws_appautoscaling_target" "service" {
  service_namespace  = "ecs"
  scalable_dimension = "ecs:service:DesiredCount"
  min_capacity       = var.scheduled_min_capacity # 0
  max_capacity       = var.scheduled_max_capacity # 1
  resource_id        = "service/${local.cluster_name}/${local.service_name}"
}

このコードは、あなたがすでにECSサービスをプロビジョニングしていることを前提としています。たとえば:

# ecs-service.tf

resource "aws_ecs_service" "service" {
  name    = local.service_name
  cluster = local.cluster_name
  [...省略(関連しない部分)...]
}

02. スケジュールされたアクションを定義する

サービスをスケールインおよびアウトするためには、少なくとも2つのスケジュールされたアクションが必要です。一つはタスクの数を増やすために、もう一つは減らすために。

# autoscaling.tf

...[aws_appautoscaling_targetのコードは省略]...

resource "aws_appautoscaling_scheduled_action" "scale_service_out" {
  name               = "${local.service_name}-scale-out"
  service_namespace  = aws_appautoscaling_target.service.service_namespace
  resource_id        = aws_appautoscaling_target.service.resource_id
  scalable_dimension = aws_appautoscaling_target.service.scalable_dimension
  schedule           = "cron(0 6 * * ? *)"
  timezone           = "Europe/London"

  scalable_target_action {
    min_capacity = var.scheduled_max_capacity # 1
    max_capacity = var.scheduled_max_capacity # 1
  }
}

resource "aws_appautoscaling_scheduled_action" "scale_service_in" {
  name               = "${local.service_name}-scale-in"
  service_namespace  = aws_appautoscaling_target.service.service_namespace
  resource_id        = aws_appautoscaling_target.service.resource_id
  scalable_dimension = aws_appautoscaling_target.service.scalable_dimension
  schedule           = "cron(0 21 * * ? *)"
  timezone           = "Europe/London"

  scalable_target_action {
    min_capacity = var.scheduled_min_capacity # 0
    max_capacity = var.scheduled_min_capacity # 0
  }

  depends_on = [aws_appautoscaling_scheduled_action.scale_service_out]
}

開発用クラスターでは、1日のほとんどの時間で全てのタスクをシャットダウンしていますが、製造環境では少なくとも1つ残し、オフィス時間中は最大で3つまで増やします。

そのためには、次の変数も必要です:

# vars.tf
variable "scheduled_min_capacity" {}
variable "scheduled_max_capacity" {}

開発用:

# config/dev/terraform.tfvars
scheduled_min_capacity = 0
scheduled_max_capacity = 1

そして製造用:

# config/prod/terraform.tfvars
scheduled_min_capacity = 1
scheduled_max_capacity = 3

さて、これらの変更を検証してテストする方法を理解しましょう。

テストしてみよう

これらのリソースをデプロイして、すべてがうまく機能しているかを確認するためには、もちろんECSダッシュボードを見つめ、リフレッシュして、ECSタスクの数が増減しているのを見ることができます。しかし、より効率的な方法が必要であれば、aws-cliの使用をお勧めします。どうやら、この情報はAWSコンソールでは利用できないようです。

このコマンドを実行して、既存のスケジュールされたアクションを表示します:

aws application-autoscaling describe-scheduled-actions --service-namespace ecs

結果はこのようになるはずです:

{
    "ScheduledActions": [        
        {
            "ScheduledActionName": "<SERVICE-NAME>-scale-up",
            "ScheduledActionARN": "arn:aws:autoscaling:<AWS-REGION>:<AWS-ACCOUNT-ID>:scheduledAction:<ID>:resource/ecs/service/<CLUSTER-NAME>/<SERVICE-NAME>:scheduledActionName/<SERVICE-NAME>-scale-up",
            "ServiceNamespace": "ecs",
            "Schedule": "cron(0 6 * * ? *)",
            "ResourceId": "service/<CLUSTER-NAME>/<SERVICE-NAME>",
            "ScalableDimension": "ecs:service:DesiredCount",
            "ScalableTargetAction": {
                "MinCapacity": 1,
                "MaxCapacity": 1
            }
        },
        {
            "ScheduledActionName": "<SERVICE-NAME>-scale-down",
            "ScheduledActionARN": "arn:aws:autoscaling:<AWS-REGION>:<AWS-ACCOUNT-ID>:scheduledAction:<ID>:resource/ecs/service/<CLUSTER-NAME>/<SERVICE-NAME>:scheduledActionName/<SERVICE-NAME>-scale-down",
            "ServiceNamespace": "ecs",
            "Schedule": "cron(0 23 * * ? *)",
            "ResourceId": "service/<CLUSTER-NAME>/<SERVICE-NAME>",
            "ScalableDimension": "ecs:service:DesiredCount",
            "ScalableTargetAction": {
                "MinCapacity": 0,
                "MaxCapacity": 0
            }
        } 
    ]
}

また、最近のオートスケーリングの活動をチェックできます(これはECSサービスのイベントページでも利用可能です):

aws application-autoscaling describe-scaling-activities --service-namespace ecs

出力:

{
    "ScalingActivities": [
        {
            "ActivityId": "a7edfe9b-b924-4468-a129-736ce0a06078",
            "ServiceNamespace": "ecs",
            "ResourceId": "service/<CLUSTER-NAME>/<SERVICE-NAME>",
            "ScalableDimension": "ecs:service:DesiredCount",
            "Description": "Desired count set to 1.",
            "Cause": "Minimum capacity set to 1",
            "StartTime": "2021-08-24T06:00:16.520000+01:00",
            "EndTime": "2021-08-24T06:00:47.551000+01:00",
            "StatusCode": "Successful",
            "StatusMessage": "Successfully set desired count to 1. Change successfully fulfilled by ecs."
        }
]
}

### まとめ

スケジュールされたオートスケーリングは、ECSクラスターにオートスケーリングを導入する簡単な方法です。

リソースを節約し、最適化するという概念はエキサイティングだと思います。必要ない時にはマシンをオフにするという考えは、正しいことのように思えます。

私は必ずしもスケーラビリティの課題を解決するためにスケジュールされたオートスケーリングを推奨するわけではありません。たとえば、予測不可能なワークロードを持っている場合は、[トラッキングオートスケーリング](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service-autoscaling-targettracking.html)の方が適しているかもしれません。

この記事がお役に立てば幸いです。🙏

### 出典

スケジュールされたオートスケーリングの設定方法を学ぶために、次のドキュメントやブログを使用しました。あなたにも役立つと思います:

* [https://keita.blog/2018/01/29/aws-application-auto-scaling-for-ecs-with-terraform/](https://keita.blog/2018/01/29/aws-application-auto-scaling-for-ecs-with-terraform/)
* [https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/appautoscaling_scheduled_action](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/appautoscaling_scheduled_action)
* [https://gist.github.com/toricls/fea9d8a4eb606a27f6666a1abc6a6fd8](https://gist.github.com/toricls/fea9d8a4eb606a27f6666a1abc6a6fd8)<br><br>こちらの記事はdev.toの良い記事を日本人向けに翻訳しています。<br>[https://dev.to/andreafalzetti/how-to-configure-ecs-fargate-scheduled-autoscaling-556c](https://dev.to/andreafalzetti/how-to-configure-ecs-fargate-scheduled-autoscaling-556c)