(O+P)ut

アウトプット



(O+P)ut

エンジニアのアウトプット

【AWS/ECS】タスク定義(Task Definition)をCUIで更新する

スポンサーリンク

はじめに

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で行えます。

以上、ご参考になれば幸いです。