Amazon ECSで、サービスが参照するタスク定義のリビジョンのみを更新する

# What's？

こういうことがやりたかった、と。

* Amazon ECSで、サービスが参照するタスク定義のリビジョンを更新したい
* タスク定義の中身は特に変えたくなくて、とにかくリビジョンだけ上げたい

参照するコンテナイメージが`latest`などで同じ時に新しいイメージを使いたい場合や、参照しているParameter Storeの値が変わった場合などに。

ただ、ここに載せている方法は`deploymentController`が`ECS`の場合のみです。


# 環境

実行環境は、こちら。

```shell
$ aws --version
aws-cli/2.0.28 Python/3.7.3 Linux/4.15.0-109-generic botocore/2.0.0dev32
```


# コマンド

`aws ecs describe-task-definition`コマンドの結果から、不要なものを削って`aws ecs register-task-definition`コマンドに流し込みます。

```shell
$ aws ecs describe-task-definition --task-definition [タスク定義名] | \
  jq '.taskDefinition' | jq -M 'del(.taskDefinitionArn) | del(.revision) | del(.status) | del(.requiresAttributes) | del(.compatibilities)' | \
  xargs -0 aws ecs register-task-definition --family [タスク定義名] --cli-input-json
```

JSONファイルの実体は、作成したくないですよ、と。

`aws ecs register-task-definition`コマンドの`--cli-input-json`オプションで受け取るJSONに、不要な要素が入ったままだとこんな感じになります。

```shell
$ aws ecs describe-task-definition --task-definition [タスク定義名] | \
  jq '.taskDefinition' | \
  xargs -0 aws ecs register-task-definition --family [タスク定義名] --cli-input-json

Parameter validation failed:
Unknown parameter in input: "taskDefinitionArn", must be one of: family, taskRoleArn, executionRoleArn, networkMode, containerDefinitions, volumes, placementConstraints, requiresCompatibilities, cpu, memory, tags, pidMode, ipcMode, proxyConfiguration, inferenceAccelerators
Unknown parameter in input: "revision", must be one of: family, taskRoleArn, executionRoleArn, networkMode, containerDefinitions, volumes, placementConstraints, requiresCompatibilities, cpu, memory, tags, pidMode, ipcMode, proxyConfiguration, inferenceAccelerators
Unknown parameter in input: "status", must be one of: family, taskRoleArn, executionRoleArn, networkMode, containerDefinitions, volumes, placementConstraints, requiresCompatibilities, cpu, memory, tags, pidMode, ipcMode, proxyConfiguration, inferenceAccelerators
Unknown parameter in input: "requiresAttributes", must be one of: family, taskRoleArn, executionRoleArn, networkMode, containerDefinitions, volumes, placementConstraints, requiresCompatibilities, cpu, memory, tags, pidMode, ipcMode, proxyConfiguration, inferenceAccelerators
Unknown parameter in input: "compatibilities", must be one of: family, taskRoleArn, executionRoleArn, networkMode, containerDefinitions, volumes, placementConstraints, requiresCompatibilities, cpu, memory, tags, pidMode, ipcMode, proxyConfiguration, inferenceAccelerators
```

`[タスク定義名]`の部分を埋めるのが面倒だったら、環境変数の利用でも…。

```shell
$ TASK_DEFINITION_NAME=[タスク定義名]
$ aws ecs describe-task-definition --task-definition ${TASK_DEFINITION_NAME} | \
  jq '.taskDefinition' | jq -M 'del(.taskDefinitionArn) | del(.revision) | del(.status) | del(.requiresAttributes) | del(.compatibilities)' | \
  xargs -0 aws ecs register-task-definition --family ${TASK_DEFINITION_NAME} --cli-input-json
```

最後に、このタスク定義を使用するサービスを更新して完了です。

```shell
$ aws ecs update-service --cluster [クラスタ名] --service [サービス名] --task-definition [タスク定義名]
```

デプロイ方法（`deploymentController`）が`ECS`の場合は、ローリング更新が始まります。

あとは、サービスの認識しているリビジョンが変わったのを眺めつつ、実際に動作するコンテナが言われ変わるのを待ちましょう。

```shell
$ aws ecs describe-services --cluster [クラスタ名] --services [サービス名] | grep taskDefinition
            "taskDefinition": "arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxx:task-definition/[タスク定義名]:[リビジョン]",
                    "taskDefinition": "arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxx:task:task-definition/[タスク定義名]:[リビジョン]",
```

なお、`deploymentController`に`CODE_DEPLOY`を指定している場合は、`aws ecs update-service`実行時に以下のようなエラーが出て、実行に失敗してしまいます。

```shell
An error occurred (InvalidParameterException) when calling the UpdateService operation: Unable to update task definition on services with a CODE_DEPLOY deployment controller. Use AWS CodeDeploy to trigger a new deployment.
```