はじめに
ECSのタスク定義に修正を加える場合、AWSの管理コンソールにて”新しいリビジョンの作成(Create new revision/Create new revision with JSON)から行います。
一方でコンテナイメージのタグのみを変更する等、軽微かつ機械的な置換で行えるものはCUIから操作したい場合もあると思います。というわけで、今回は自動化を想定してAWSCLIにてタスク定義に微修正を加え、新たなバージョンで作成する流れを検証しました。
環境情報
- ECS Fargate 1.4
- aws-cli/2.15.5
更新する前のタスク定義を取得する
全体の流れとしては参考にするタスク定義のJSON情報を取得し、awscliで登録できるように整形、最後に登録します。
まずは修正前のタスク定義の情報を取得するため、aws ecs list-task-definitions
を行います。下記のような形でタスク定義とリビジョン毎に並んでいるので
{ "taskDefinitionArns": [ "arn:aws:ecs:ap-northeast-1:xx:task-definition/xx:2", "arn:aws:ecs:ap-northeast-1:xx:task-definition/xx:1", ...
適当に整形をしてARNを取得します。
$ aws ecs list-task-definitions | grep <TASKDEFINITION_NAME> | tail -n 1 | sed -e "s/ //g" | sed -e 's/"//g'| cut -d"," -f1 arn:aws:ecs:ap-northeast-1:xx:task-definition/xx:1
同タスク定義の情報を以下コマンドで出力します。
$ aws ecs describe-task-definition --task-definition arn:aws:ecs:ap-northeast-1:xx:task-definition/xx:1 > test.json
タスク定義に修正内容を反映させる
このままのファイルで登録ができれば良いのですが、以下のようにエラーとなります。
$ aws ecs register-task-definition --cli-input-json file://test.json Parameter validation failed: Missing required parameter in input: "family" Missing required parameter in input: "containerDefinitions" Unknown parameter in input: "taskDefinition", must be one of: family, taskRoleArn, executionRoleArn, networkMode, containerDefinitions, volumes, placementConstraints, requiresCompatibilities, cpu, memory, tags, pidMode, ipcMode, proxyConfiguration, inferenceAccelerators, ephemeralStorage, runtimePlatform
タスク定義のdescribeした結果には登録時には不要の情報があるので、以下で不要な項目を削除して新たなJSONを作成します。
$ jq '.taskDefinition | del (.taskDefinitionArn, .revision, .status, .requiresAttributes, .compatibilities, .registeredAt, .registeredBy)' test.json > hoge.json
コンテナイメージのタグを変える場合は、sedコマンド等で置換処理も行います。
cat hoge.json | sed -e "s/<BEFORE>/<AFTER>/"
新たなリビジョンのタスク定義を作成する
編集したJSONファイルで登録を試みると
$ aws ecs register-task-definition --cli-input-json file://hoge.json
新たなリビジョンが自動で採番されてタスク定義が作成されます。
{ "taskDefinition": { "taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:xx:task-definition/xx:2", ...
リスト表示をすると確かに一覧に追加されており、タスク定義として新たなバージョンで作成が行えたことが分かります。
$ aws ecs list-task-definitions | grep <TASKDEFINITION_NAME> | tail -n 1 | sed -e "s/ //g" | sed -e 's/"//g'| cut -d"," -f1 arn:aws:ecs:ap-northeast-1:xx:task-definition/xx:2
ちなみに新たなタスク定義のdescribe-task-definition
と比較を行うと以下のように差分として出力されました。(明示的に変更した箇所以外)
$ diff test.json new.json 3c3 < "taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:xx:task-definition/xx:1", --- > "taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:xx:task-definition/xx:2", 35c35 < "revision": 1, --- > "revision": 2, 84,85c84,85 < "registeredAt": "...", < "registeredBy": "..." --- > "registeredAt": "...", > "registeredBy": "..."
registeredByにはGUIで作成をするとそのIAMユーザ、CUIで作成をするとAWSコマンドに紐づいているロールやユーザが入っています。
終わりに
上記ステップにて、機械的にタスク定義の更新ができることが分かりました。ここからサービスを新しいタスク定義で更新する場合も
$ aws ecs update-service --force-new-deployment --cluster xx --service xx --task-definition xx
にて同じくCUIで行えます。
以上、ご参考になれば幸いです。