Amazon ECS (以下、ECS) のタスク定義は aws cli などの describe-task-definition で JSON 形式で出力することができますが、その JSON ファイルはそのままではタスク定義の登録や更新(register-task-definition)には使えなかったりします。
うまく整形してやれば、タスク定義の登録や更新に利用できるので jq などを駆使してさくっと整形する方法をメモっておきます。

はじめに

はじめに、 describe-task-definition で出力した JSON ファイルを register-task-definition でそのまま更新しようとするとどうなるでしょう。

aws ecs describe-task-definition --task-definition hoge-task > task-def.json
aws ecs register-task-definition --cli-input-json fileb://task-def.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

出力した task-def.json ファイルを見ていただければわかりますが、そもそも階層(と表現して良いのか?)があってなさそうです。

jq コマンドで整形

そこで jq コマンドで taskDefinition の中を取り出すようにしてみます。

aws ecs describe-task-definition --task-definition hoge-task | \
  jq '.taskDefinition' > task-def.json
aws ecs register-task-definition --cli-input-json fileb://task-def.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

とは言え、 以下のパラメータを除けばいけそうです。

  • taskDefinitionArn
  • revision
  • status
  • requiresAttributes
  • compatibilities

今度は jqdel 関数を使ってこれらの値を削除していきます。複数の値を指定する時はカンマで区切れば良いみたいです。

aws ecs describe-task-definition --task-definition hoge-task | \
  jq '.taskDefinition | del (.taskDefinitionArn, .revision, .status, .requiresAttributes, .compatibilities)' > task-def.json
aws ecs register-task-definition --cli-input-json fileb://task-def.json

今度はエラーなく登録ができました。これで良さそうです。

おまけ

出力したタスク定義を他のリージョン向けに登録したい、なんていうケースには sed コマンドも使ってタスク定義内のリージョンを書き換えてやります。例えば以下の例は、バージニア北部(us-east-1)のタスク定義をオレゴン(us-west-2)向けのタスク定義に書き換え、オレゴンのタスク定義として登録しています。

aws ecs describe-task-definition --task-definition hoge-task --region us-east-1 | \
  jq '.taskDefinition | del (.taskDefinitionArn, .revision, .status, .requiresAttributes, .compatibilities)' | \
  sed -e 's/us-east-1/us-west-2/g' > task-def.json
aws ecs register-task-definition --cli-input-json fileb://task-def.json --region us-west-2

最後に・・・

この投稿は個人的なものであり、所属組織を代表するものではありません。ご了承ください。