ECSタスク定義をコンソールから作って後悔した後、コード管理するため最速でJSON登録可能にする超愚直な方法
いつもこってりしたリード文を書く自分ですが、今日はもう、全部タイトルに書いた。
小ネタなのにタイトル長くない?! ( ゚д゚) ガタッ / ヾ __L| / ̄ ̄ ̄/_ \/ /
せやな。
ECSのタスク定義登録は項目が多くて大変
ECSのタスク定義は、長年のECSの機能拡張に伴い設定可能な項目が非常に多くなっています。そんな複雑なタスク定義ですが、登録方法は大きく分けて3つあります。
- マネジメントコンソールから登録
- タスク定義のJSONを作成し、AWS CLIから
register-task-definition
を使って登録 - CloudFormationなどIaCを使って登録
ECSのタスク定義作成に慣れていない場合、項目の関連性が把握しやすいマネジメントコンソールからの登録を自分はおすすめしています。
JSONからの登録方法もテンプレートが公式で案内(タスク定義テンプレート)されていますが、最初は項目が多すぎていきなりのJSON作成は辛いと思います。
また、CloudFormationも良い選択肢なのですが、いかんせん最新プロパティがCloudFormationに対応するまでのタイムラグが結構あったりします。
最初はマネジメントコンソール⇢必要に応じてJSONに移行するのがわかりやすい
最初、マネジメントコンソールで登録しそれをベースに運用してく方法ももちろんありです。ただ、環境変数や設定項目が多くなっていくに従い、「画面でやるの辛い…し、コード管理したいYO!!」という気持ちがでてくる場合も多いです。
そんなとき、1からJSONを作り直しても良いんですが、既存の登録内容との整合性を確認するのも大変なので、コンソール登録した内容をJSONに反映するこの記事が役に立つってことです。
登録用JSONを作成するのが案外難しい
「そんなん、既存の登録内容からその内容をJSONで出力してそれをそのまま使えばええやん?」と思いますよね。はい。そんなAPIはありません。もちろん、タスク定義の内容を表示するAPIはあるんですが、このdescribe-task-definition
コマンドを使って出力した内容は、そのままではタスク定義登録用には使えないため、何かしらの加工が必要となります。
実はやろうとしていることは、弊社もこのこちらの記事と完全に同じなのですが、実施方法が異なります。
describe-task-definitionで取得したJSONはそのままではregister-task-definitionで登録できないお話 | Developers.IO
ECSタスク定義で利用できるJSONを作る方法
前置き長くなりましたが、ここから実際にマネジメントコンソールに登録しているECSタスク定義から、登録に利用できるJSONの作成方法を解説していきます。
元ネタのJSONを取得する
最初に編集するための元ネタとなるJSONを取得します。今回のJSONはマネジメントコンソールにのみ表示されているので、ものすごい愚直な方法でとってきますYO
マネジメントコンソールのECSタスク定義メニューから該当のタスク定義を開きます。ここで[Create new revision]をクリック。
タスク定義編集画面に遷移するので、ここで、画面一番下にある[Conrigure via JSON]ボタンをクリック。
すると、今回登録の元ネタに利用できるJSONが表示されます。
これをマウスで選択して適当なエディタにコピーしてJSONとして保存します。「マウスで選択!?まじかよ!?」と思うかもですが、マジです。ちょっと見た限りこの内容をCLIから取得する方法はありません。
こんな感じで取得できたでしょうか?ファイル名は、ecs-task.json
にしています。
{ "ipcMode": null, "executionRoleArn": null, "containerDefinitions": [ { "dnsSearchDomains": null, "logConfiguration": null, "entryPoint": null, "portMappings": [ { "hostPort": 8000, "protocol": "tcp", "containerPort": 8000 } ], "command": null, "linuxParameters": null, "cpu": 0, "environment": [], "resourceRequirements": null, "ulimits": null, "dnsServers": null, "mountPoints": [ { 〜〜以下略〜〜 }
余談:タスク定義を表示したとき、画面に別タブで[JSON]があることを知っている人も多いと思います。このJSON使って試してみたんですが、エラーの解消方法がわかりにくかったため、元ネタのJSONは上で案内したものを使っています。
一度登録を試してみてエラーを表示させる
このJSONがそのままCLIから登録できればよいのですが、それができません。試しにaws cliのregister-task-definition
をつかって登録しようとすると、以下の感じのエラーが大量にでます。下の例では、タスク定義fargate-efs-mount-test
に、JSONを登録しています。
aws ecs register-task-definition --family fargate-efs-mount-test --cli-input-json file://ecs-task.json Parameter validation failed: Invalid type for parameter ipcMode, value: None, type: <class 'NoneType'>, valid types: <class 'str'> Invalid type for parameter executionRoleArn, value: None, type: <class 'NoneType'>, valid types: <class 'str'> Invalid type for parameter containerDefinitions[0].dnsSearchDomains, value: None, type: <class 'NoneType'>, valid types: <class 'list'>, <class 'tuple'> Invalid type for parameter containerDefinitions[0].logConfiguration, value: None, type: <class 'NoneType'>, valid types: <class 'dict'> Invalid type for parameter containerDefinitions[0].entryPoint, value: None, type: <class 'NoneType'>, valid types: <class 'list'>, <class 'tuple'> Invalid type for parameter containerDefinitions[0].command, value: None, type: <class 'NoneType'>, valid types: <class 'list'>, <class 'tuple'> Invalid type for parameter containerDefinitions[0].linuxParameters, value: None, type: <class 'NoneType'>, valid types: <class 'dict'> Invalid type for parameter containerDefinitions[0].resourceRequirements, value: None, type: <class 'NoneType'>, valid types: <class 'list'>, <class 'tuple'> Invalid type for parameter containerDefinitions[0].ulimits, value: None, type: <class 'NoneType'>, valid types: <class 'list'>, <class 'tuple'> Invalid type for parameter containerDefinitions[0].dnsServers, value: None, type: <class 'NoneType'>, valid types: <class 'list'>, <class 'tuple'> Invalid type for parameter containerDefinitions[0].mountPoints[0].readOnly, value: None, type: <class 'NoneType'>, valid types: <class 'bool'> Invalid type for parameter containerDefinitions[0].workingDirectory, value: None, type: <class 'NoneType'>, valid types: <class 'str'> Invalid type for parameter containerDefinitions[0].secrets, value: None, type: <class 'NoneType'>, valid types: <class 'list'>, <class 'tuple'> Invalid type for parameter containerDefinitions[0].dockerSecurityOptions, value: None, type: <class 'NoneType'>, valid types: <class 'list'>, <class 'tuple'> Invalid type for parameter containerDefinitions[0].memory, value: None, type: <class 'NoneType'>, valid types: <class 'int'> 〜〜以下略〜〜
エラーを潰して登録できるJSONを作っていく
あとは、エラー内容を確認しながらJSONを編集していくのみです。エラー内容は大量にありますが、基本的にエラー内容は「プロパティの中身がnullやで」と言っているだけなので、値が設定されていないnullのプロパティをどんどん削除していきます。
ある程度不要な項目削ったら、再度登録してみて、エラーがでたらまたつぶし〜っていうのを繰り返します。
最終的にエラーが無くなって、作成したJSONからregister-task-definition
が実行できたら、あなたの勝ちです! お疲れさまでした。
$ aws ecs register-task-definition --family fargate-efs-mount-test --cli-input-json file://ecs-task.json { "taskDefinition": { "taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:629895769338:task-definition/fargate-efs-mount-test:16", "containerDefinitions": [ { "name": "cloud-commander", "image": "coderaiser/cloudcmd:latest", 〜〜以下略〜〜
これをキッカケにECSタスク定義のコード管理に挑戦してみよう!
この記事書いておきながら、「もっと他の方法無いのかなぁ…」と思ったりしましたが、まぁ無さそうでした。ECSのタスク定義、設定項目が非常に多いのですが、マネジメントコンソール自体は非常によくできていると思うので、うまく学習と運用でそれぞれの手段を比較しながら、今回の記事を参考にしていただければと思います。
それでは、今日はこのへんで。濱田(@hamako9999)でした。