はじめに

こんにちは、そしてこんばんは!
クラウドインテグレーション事業部の大嵩です。

今回は、Amazon Auroraリードレプリカ(Aurora)のAutoScalingを、日付や繰り返しを指定してスケジューリングする方法をご紹介します!

検証したこと

Auroraでは、マネジメントコンソール上から、AutoScalingポリシーを作成できますが、それでは日時指定などはできず、CPU使用率を閾値に使用する形になります。
そのため、今回はApplication Auto ScalingのAPIを使って、AWS CLIから、スケジュールを登録できるか検証します。

Applicaiton AutoScalingとは

まずはスケジュールターゲットの作成

スケジュールを登録するにあたって、ターゲットの作成が必要になります。
これは、以下の内容に対してポリシーを作成するという動きになるためです。

  • Application Auto Scalingの対応するサービスのうち、どのサービスか
  • リソースID
  • スケールするリソース種別(例:リードレプリカ)
  • 最小/最大キャパシティ

登録コマンドは以下のような形になります!

aws application-autoscaling register-scalable-target \
    --service-namespace rds \
    --resource-id cluster:Auroraクラスタ名 \
    --scalable-dimension rds:cluster:ReadReplicaCount \ # ここでリードレプリカを指定
    --min-capacity 1 \
    --max-capacity 15

登録が完了すると、コマンド実行結果として以下のようなARNが返ってきます。

{
    "ScalableTargetARN": "arn:aws:application-autoscaling:ap-northeast-1:アカウントID:scalable-target/XXXX"
}

実際にスケジュールを登録する

では、実際にスケジュールを登録してみます。
例えばですが、 2025/04/09 23:50 に最小台数10台へスケールアウトする場合は以下のようになります。
--timezone部分で、Asia/Tokyoを指定することで、JSTでの入力が可能です!

aws application-autoscaling put-scheduled-action \
    --schedule "at(2025-04-09T23:50:00)" \
    --timezone "Asia/Tokyo" \
    --scalable-target-action MinCapacity=10 \
    --scheduled-action-name rds-scaleout-20250409235000 \
    --service-namespace rds \
    --resource-id cluster:クラスタ名 \
    --scalable-dimension rds:cluster:ReadReplicaCount

イベント履歴を見てみる

CloudTrailのイベント履歴で、23:50の CreateDBInstance アクションを確認できました!
問題なくリードレプリカが追加されているようですね!

{
    "eventVersion": "1.08",
    "userIdentity": {
        "type": "AssumedRole",
        "principalId": "XXXX:AutoScaling-UpdateDesiredCapacity",
        "arn": "arn:aws:sts::アカウントID:assumed-role/AWSServiceRoleForApplicationAutoScaling_RDSCluster/AutoScaling-UpdateDesiredCapacity",
        "accountId": "アカウントID",
        "accessKeyId": "XXXX",
        "sessionContext": {
            "sessionIssuer": {
                "type": "Role",
                "principalId": "XXXX",
                "arn": "arn:aws:iam::アカウントID:role/aws-service-role/rds.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_RDSCluster",
                "accountId": "アカウントID",
                "userName": "AWSServiceRoleForApplicationAutoScaling_RDSCluster"
            },
            "webIdFederationData": {},
            "attributes": {
                "creationDate": "2025-04-09T14:50:46Z",
                "mfaAuthenticated": "false"
            }
        },
        "invokedBy": "rds.application-autoscaling.amazonaws.com"
    },
    "eventTime": "2025-04-09T14:50:48Z",
    "eventSource": "rds.amazonaws.com",
    "eventName": "CreateDBInstance",
    "awsRegion": "ap-northeast-1",
    "sourceIPAddress": "rds.application-autoscaling.amazonaws.com",
    "userAgent": "rds.application-autoscaling.amazonaws.com",
    "requestParameters": {
        "dBInstanceIdentifier": "application-autoscaling-XXXX",
        "dBInstanceClass": "db.r5.xlarge",
        "engine": "aurora-postgresql",
        "dBParameterGroupName": "パラメータグループ名",
        "publiclyAccessible": false,
        "dBClusterIdentifier": "クラスタ名",
        "promotionTier": 15
    },
~ 割愛 ~
    "requestID": "XXXX",
    "eventID": "XXXX",
    "readOnly": false,
    "eventType": "AwsApiCall",
    "managementEvent": true,
    "recipientAccountId": "アカウントID",
    "eventCategory": "Management"
}

次に定期スケジュールを登録する

では、次に定期的なスケジュールを登録してみたいと思います。
どうやって登録するかといいますと、日付を指定していた部分で、今度は cron式を指定します。
例として、毎日23:30に最低台数6台ヘスケールする場合は下記のようになります!
日付指定と同様に、timezoneを指定することで、JSTでのcronを書くことができます!

aws application-autoscaling put-scheduled-action \
    --schedule "cron(30 23 * * ? *)" \ # ここでcronを指定
    --timezone "Asia/Tokyo" \
    --scalable-target-action MinCapacity=6 \
    --scheduled-action-name rds-scaleout-daily-2330 \
    --service-namespace rds \
    --resource-id cluster:クラスタ名 \
    --scalable-dimension rds:cluster:ReadReplicaCount

イベント履歴を見てみる

それでは、イベント履歴をのぞいてみましょう!

なんと、レプリカが追加されていない!!

なぜ、追加されなかったのか

今回の環境は、AuroraクラスタにCPU使用率を閾値とした既存のスケーリングポリシーがあります。
そのポリシーのスケールインと、今回のスケジュールのスケールアウトが衝突してしまったのが原因です。。

具体的には、リードレプリカ削除が23:28~23:36 にかけて行われていることから、その間クラスタは「利用可能」状態ではなく、「削除中」となっていたことになります。
これにより、正常にスケールアウトが動作しませんでした。
下記AWSドキュメントにも記載があります。

Aurora Auto Scaling は、DB クラスターが利用可能な状態にある場合のみ、DB クラスターをスケーリングします。

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/Aurora.Integrating.AutoScaling.html#Aurora.Integrating.AutoScaling.BYB

スケール動作衝突の対処法

スケールインでインスタンス削除時に、スケールアウトができないのは想定外でした。。
現状対処する方法として、cronを変更することで、対策が可能です!
力技ですが、数分ごとに最小台数変更を繰り返すものになります。
今回の例でいきますと、23:30にスケールアウトしていたいため、猶予を持たせて23:20から23:50まで5分ごとに繰り返します。
cronを以下のように変えてみます。

cron(20-50/5 23 * * ? *)

イベント履歴を見てみる

下記のような形で、繰り返し最小キャパシティの指定が行われているのがわかります。
これにより、クラスタの状態が「利用可能」意外であったとしても、正常に戻ったときにキャパシティの変更を認識して、スケールアウトを実行することができるようになります。

注意!!

今回は、スケールアウトといいつつ、最小台数を変更しております。
そのため、スケールインのアクションを別途設定しないと台数が維持されてしまいます!
お気をつけください!!
単純に、MinCapacityを1とするものになります。

aws application-autoscaling put-scheduled-action \
    --schedule "at(2025-04-10T02:00:00)" \
    --timezone "Asia/Tokyo" \
    --scalable-target-action MinCapacity=1 \ # 1台に戻す場合
    --scheduled-action-name アクション名 \
    --service-namespace rds \
    --resource-id cluster:クラスタ名 \
    --scalable-dimension rds:cluster:ReadReplicaCount

まとめ

今回の検証から、下記が明らかになりました!

  • AuroraリードレプリカのAuto Scalingは、AWS CLI (Application Auto Scaling API) を使えば時間指定や定期実行(cron) が可能です!
  • register-scalable-target で対象を登録後、put-scheduled-action で at() や cron() を使ってスケジュールを設定します。
  • 注意点: cronスケジュールは、既存のCPUベースポリシー等と動作タイミングが衝突すると失敗することがあります。
  • 対策: 衝突が起こりうる場合は、cron設定でターゲット時刻の前後に短間隔で繰り返し実行させることで、安定動作が期待できます。

Application Auto Scalingを使って、みなさんも良いスケールライフを!
この記事がどなたかの参考になりますと幸いです。