はじめに

今回は小ネタです。 Application Auto Scaling のスケジュールされたアクションの例 - Application Auto Scaling などでは aws-cli による Appliction Auco Scaling のスケジュール方法が示されていました。
しかし、CloudFormation によるものが Web 上でうまく見つけられなかったのでメモ程度に記しておきます。

要件

ECS サービス fuga/hoge において

  • 毎月、1日の3時から2日の18時まで ECS タスクが 5 つ稼働している
  • 上記の時刻以外では
    • ECS タスク数の制限は 最小: 0, 最大: 5 となる
    • 上記制限の間で任意の CloudWatch Alarm のメトリクスを指標としてスケールイン・スケールアウトする

CloudFormation テンプレート

AWSTemplateFormatVersion: "2010-09-09"
Description: 'Scheduled Auto Scaling'
Resources:
  ScalableTarget:
    Type: AWS::ApplicationAutoScaling::ScalableTarget
    Properties:
      MaxCapacity: 5
      MinCapacity: 0
      ResourceId: service/fuga/hoge
      RoleARN: arn:aws:iam::XXXXXXXXXXXX:role/aws-service-role/ecs.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_ECSService
      ScalableDimension: ecs:service:DesiredCount
      ServiceNamespace: ecs
      ScheduledActions:
        - ScheduledActionName: "start-monthly"
          ScalableTargetAction:
            MaxCapacity: 5
            MinCapacity: 5
          Schedule: "cron(0 3 1 * ? *)"
          Timezone: "Asia/Tokyo"
        - ScheduledActionName: "end-monthly"
          ScalableTargetAction:
            MaxCapacity: 5
            MinCapacity: 0
          Schedule: "cron(0 18 2 * ? *)"
          Timezone: "Asia/Tokyo"
  ScalingPolicy:
    Type : AWS::ApplicationAutoScaling::ScalingPolicy
    Properties:
      PolicyName: ScalePolicy
      PolicyType: StepScaling
      ScalingTargetId: !Ref ScalableTarget
      StepScalingPolicyConfiguration:
        AdjustmentType: ExactCapacity
        Cooldown: 300
        MetricAggregationType: Average
        StepAdjustments:
          - ScalingAdjustment: 0
            MetricIntervalLowerBound: 0
            MetricIntervalUpperBound: 1
          - ScalingAdjustment: 1
            MetricIntervalLowerBound: 1
            MetricIntervalUpperBound: 100
          - ScalingAdjustment: 2
            MetricIntervalLowerBound: 100
            MetricIntervalUpperBound: 200
          - ScalingAdjustment: 3
            MetricIntervalLowerBound: 200
            MetricIntervalUpperBound: 300
          - ScalingAdjustment: 4
            MetricIntervalLowerBound: 300
            MetricIntervalUpperBound: 400
          - ScalingAdjustment: 5
            MetricIntervalLowerBound: 400

(余談)Timezone について

Timezone にあるとおり、時刻の指定時にタイムゾーンを記すことができます。
スケジュールされた ECS タスク(スケジュールされたオートスケールではなく)だと スケジュールに従って実行する Amazon EventBridge ルールの作成 - Amazon EventBridge にあるようにタイムゾーンの指定は無く UTC 一択となっていますので、この設定属性は大変助かります。 なお、タイムゾーンの書式については

Valid values are the canonical names of the IANA time zones supported by Joda-Time (such as Etc/GMT+9 or Pacific/Tahiti). For more information, see https://www.joda.org/joda-time/timezones.html.

PutScheduledAction - Application Auto Scaling

とあるとおり、 Joda-Time – Java date and time API - Time Zones に記載の IANA のタイムゾーンID を使うこととなっています。
CloudFormation のドキュメントには直接記載がなく、関連 aws-cli の API リファレンスからたどることができました。AWS のドキュメントは複合的に見ていかないと要件が判然としないこともあるので慣れが必要ですね。

確認方法

スケーリングポリシー ScalingPolicy は Web コンソールより当該 ECS サービスにアクセスすることで設定を確認することができます。
しかし、スケーラブルターゲットのスケジュールされたアクション ScalableTarget > ScheduledActions については Web コンソールから確認ができませんでした。
よって、以下のような aws-cli コマンドでリソースの状況を確認しました。
所望の状態になっているようです。大丈夫そうですね!

$ aws application-autoscaling describe-scheduled-actions --service-namespace ecs --resource-id service/fuga/hoge
{
    "ScheduledActions": [
        {
            "ScheduledActionName": "start-monthly",
            "ScheduledActionARN": "arn:aws:autoscaling:ap-northeast-1:XXXXXXXXXXXX:scheduledAction:YYYYYYYYYYYYYYYYYYYYY:resource/ecs/service/fuga/hoge:scheduledActionName/start-monthly",
            "ServiceNamespace": "ecs",
            "Schedule": "cron(0 3 1 * ? *)",
            "Timezone": "Asia/Tokyo",
            "ResourceId": "service/fuga/hoge",
            "ScalableDimension": "ecs:service:DesiredCount",
            "ScalableTargetAction": {
                "MinCapacity": 5,
                "MaxCapacity": 5
            },
            "CreationTime": "2022-07-26T07:23:27.962000+00:00"
        },
        {
            "ScheduledActionName": "end-monthly",
            "ScheduledActionARN": "arn:aws:autoscaling:ap-northeast-1:XXXXXXXXXXXX:scheduledAction:YYYYYYYYYYYYYYYYYYYYY:resource/ecs/service/fuga/hoge:scheduledActionName/end-monthly",
            "ServiceNamespace": "ecs",
            "Schedule": "cron(0 18 2 * ? *)",
            "Timezone": "Asia/Tokyo",
            "ResourceId": "service/fuga/hoge",
            "ScalableDimension": "ecs:service:DesiredCount",
            "ScalableTargetAction": {
                "MinCapacity": 0,
                "MaxCapacity": 5
            },
            "CreationTime": "2022-07-26T07:23:27.962000+00:00"
        }
    ]
}

まとめ

CloudFormation で Appliction Auco Scaling のスケジューリングをしてみました。Appliction Auco Scaling は ECS 以外にも Aurora などの各種サービスに対応しています。コストと可用性の最適化にはとてもよい選択肢だと思うので上手に使いこなしていけるようになりたいですね。