【AWS】FargateのタスクをSchedulerを利用して日次起動にする設定

# 概要
ECS Fargateのタスク起動を日次起動にしたいことってありませんでしょうか。
例えば平日8:00-20:00の間だけ使えれば良いというな社内サービスとか。

今までECS on EC2を使っていて、その時はCloudWatchRuleでEC2 instanceのStart/Stop設定が可能だったのですが、Fargateの場合は異なる手段が必要だったので紹介します。

### 前提
Lambda関数を使って設定することもできるとのことでしたが、CW Ruleのようにマネコンから簡単に変更できるようなものがいいな〜と思っていました。

FargateのECSを対象にCloudwatchRuleでタスク数を1にする、と言う設定は可能だったのですが、タスク数を0にするルールを作成したら以下のエラーに。

> Resource handler returned message: "1 validation error detected: Value '0' at 'targets.1.member.ecsParameters.taskCount' failed to satisfy constraint: Member must have value greater than or equal to 1 

と言うことで、ECS on Fargateを利用していると、CloudwatchRuleで日次起動の設定を行うことができないことがわかったので、EventBridgeのSchedulerを利用することにしました。これであればマネコンからも簡単に変更もできます。


# 参考CFnテンプレート
以下が参考Cloudformationテンプレートです。
この「`arn:aws:scheduler:::aws-sdk:ecs:updateService`」を使った記事があまり見当たらなかったので、作成に少し苦労しました。

```yaml
Parameters:
  EnvTag:
    Type: String
    Default: "dev"
  SysTag:
    Type: String
    Default: "sample"

Resources:
  EcsClusterSample:
    Type: AWS::ECS::Cluster
    ## 略 ##

  ServiceSample:
    Type: AWS::ECS::Service
    ## 略 ##

  TaskDefinitionSample:
    Type: AWS::ECS::TaskDefinition
    ## 略 ##

  ScheduleGroup:
    Type: AWS::Scheduler::ScheduleGroup
    Properties:
      Name: !Sub ${SysTag}_${EnvTag}

  ScheduleEcsStart:
    Type: AWS::Scheduler::Schedule
    Properties:
      Name: !Sub ${SysTag}_${EnvTag}_Start_Ecs
      Description: Start Ecs
      GroupName: !Ref ScheduleGroup
      ScheduleExpression: cron(00 08 ? * MON-FRI *)
      ScheduleExpressionTimezone: Asia/Tokyo
      FlexibleTimeWindow:
        Mode: "OFF"
      State: ENABLED
      Target:
        Arn: arn:aws:scheduler:::aws-sdk:ecs:updateService
        Input: !Sub |
          {
            "Service": "${ServiceSample}",
            "Cluster": "${EcsClusterSample}",
            "DesiredCount": 1
          }
        RoleArn: !GetAtt EcsStartStopRole.Arn

  ScheduleEcsStop:
    Type: AWS::Scheduler::Schedule
    Properties:
      Name: !Sub ${SysTag}_${EnvTag}_Stop_Ecs
      Description: Stop Ecs
      GroupName: !Ref ScheduleGroup
      ScheduleExpression: cron(0 20 * * ? *)
      ScheduleExpressionTimezone: Asia/Tokyo
      FlexibleTimeWindow:
        Mode: "OFF"
      State: ENABLED
      Target:
        Arn: arn:aws:scheduler:::aws-sdk:ecs:updateService
        Input: !Sub |
          {
            "Service": "${ServiceSample}",
            "Cluster": "${EcsClusterSample}",
            "DesiredCount": 0
          }
        RoleArn: !GetAtt EcsStartStopRole.Arn

  EcsStartStopRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: EcsStartStopRole
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: scheduler.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: EcsStartStopPolicy
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - ecs:UpdateService
                Resource: "*"
```

Schedulerの公式ドキュメントはこちら。

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-scheduler-schedule.html


## CLIコマンド
ちなみに、作成したスケジューラーをCLIコマンドで参照する方法は以下です。
（最初「`aws events...`なのか？」とよくわからなくなったので...笑）

```
$ aws scheduler get-schedule --name sample_dev_Start_Ecs --region ap-northeast-1
```