aws-cliからEventBridge SchedulerでECSタスクを起動する

aws-cliから、EventBridge SchedulerからECSタスク(Fargete)を起動したかった。
あえてaws-cliからやっているサンプルが見つからなかったので、書き残しておきます。

## create-schedule
スケジュールを作成します。
ruleでは「put-rule」と「put-targets」の2段階に分かれていましたが、このコマンドは1つでtargetまで指定します。

```sh
# ECSタスクを実行する場合、長いので後述する--cli-input-jsonを使った方が良い……
aws scheduler create-schedule --name ecs-schedule \
  --schedule-expression 'cron(0 15 * * ? *)' \
  --schedule-expression-timezone 'Asia/Tokyo' \
  --flexible-time-window '{"Mode":"OFF"}' \
  --target '{"Arn":"arn:aws:ecs:us-west-2:999999999999:cluster/some-cluster","RoleArn":"arn:aws:iam::999999999999:role/service-role/Amazon_EventBridge_Scheduler_ECS_xxxxxxxxxx", "EcsParameters":{"LaunchType": "FARGATE","TaskDefinitionArn":"arn:aws:ecs:us-west-2:999999999999:task-definition/some-task","NetworkConfiguration": {"awsvpcConfiguration": {"AssignPublicIp": "DISABLED","SecurityGroups": ["sg-xxxxxxxx"],"Subnets": ["subnet-xxxxxxxx"]}}},"Input":"{\"taskRoleArn\":\"arn:aws:iam::999999999999:role/ecsTaskExecutionRole\",\"containerOverrides\":[{\"name\":\"container\",\"command\":[\"--version\"]}]}"}' \
  --region us-west-2
```
- Inputはコマンドの引数を書き換えるときなどに使います
- containerOverridesのnameは、ECS Task定義のコンテナ名と一致させます
 
### --generate-cli-skeleton
create-scheduleはjsonから入力を受け取る機能がありますが、jsonフォーマットのスケルトンを生成します。

```sh
aws scheduler create-schedule --generate-cli-skeleton > test.json
```

### --cli-input-json
jsonフォーマットから入力する場合は、以下のようなコマンドです。

```sh
aws scheduler create-schedule --cli-input-json file://test.json  
```

スケルトンから必須のものと指定したいものだけ残してやればよいです。
こんな感じで。
```json
{
    "FlexibleTimeWindow": {
        "Mode": "OFF"
    },
    "Name": "ecs-schedule",
    "ScheduleExpression": "cron(0 15 * * ? *)",
    "ScheduleExpressionTimezone": "Asia/Tokyo",
    "Target": {
        "Arn": "arn:aws:ecs:us-west-2:9999999999:cluster/some-cluster",
        "EcsParameters": {
            "LaunchType": "FARGATE",
            "NetworkConfiguration": {
                "awsvpcConfiguration": {
                    "AssignPublicIp": "DISABLED",
                    "SecurityGroups": [
                        "sg-xxxxxxxx"
                    ],
                    "Subnets": [
                        "subnet-xxxxxxxx"
                    ]
                }
            },
            "TaskDefinitionArn": "arn:aws:ecs:us-west-2:9999999999:task-definition/some-task"
        },
        "RoleArn": "arn:aws:iam::9999999999:role/service-role/Amazon_EventBridge_Scheduler_ECS_xxxxxxxxxx",
        "Input":"{\"taskRoleArn\":\"arn:aws:iam::9999999999:role/ecsTaskExecutionRole\",\"containerOverrides\":[{\"name\":\"container\",\"command\":[\"--version\"]}]}"
    }
}
```

## update-schedule
createとupdateはAPIが分かれているので使い分ける。
引数とかはcreate-scheduleと同じで大丈夫そう。

```sh
aws scheduler update-schedule --cli-input-json file://test.json  
```

## get-schedule
作ったスケジュールの取得。

```sh
aws scheduler get-schedule --name ecs-schedule
```

### 無かったらcreate-scheduleする
ちょっとした自動化に。

```sh
aws scheduler get-schedule --name ecs-schedule || aws scheduler create-schedule --cli-input-json file://test.json  
```


## delete-schedule
name指定で消せます。

```sh
aws scheduler delete-schedule --name ecs-schedule
```

## 参考

- 公式APIドキュメント
    - [scheduler](https://docs.aws.amazon.com/cli/latest/reference/scheduler/index.html)
- Terraformでやる場合
    - [ECSを動かすEventBridge SchedulerをTerraformで構築してみた](https://made.livesense.co.jp/entry/2023/02/27/083000)

- 権限周りでのトラブルシューティング
    - [ECS ＋ Fargate のタスクを EventBridge Scheduler で実行する](https://zenn.dev/ano/articles/58eca4593b2cfe)

## 以上
Targetの指定をJSONでやるのが取っ付きづらかったけど、エラーメッセージは親切で良いです。