🌟

AWS Copilot CLIで作成されるECSのタスク定義を変更してみた

2024/02/15に公開

保育ICTを愛するみなさまこんにちは、H.G.M developers T.K です。

はじめに

開発しているシステムのデプロイツールとしてAWS Copilotを採用しております。
今回はAWS Copilotで構築されるECSのタスク定義についてYAML Patchで変更する方法をご紹介します。

目的・背景

AWS CopilotのLoad Balanced Web Serviceで作成されるデフォルトのECSのログは1行ごとに別のレコードに記録されるため、一つのエラーのトレースバックなどを追うにも複数のレコードに跨って確認する必要があり、調査するときに少し手間がかかる状態でした。
ERRORの文字列で検索してもエラーの詳細は別のレコードの内容を参照しなければならず、運用上かなり不便になっていました。

同一時刻のログは1レコードにまとめて出力できるように、awslogsログドライバーのオプションに awslogs-datetime-format を追加するために、ECSのタスク定義の変更作業にあたりました。

この記事を読んで欲しい人

  • AWS Copilotの利用経験がある方
  • AWS Copilotで作成されたECSのタスク定義をカスタマイズしたい方

開発環境

  • MacBook Pro M1
  • AWS Copilot CLI: 1.30.1

やったこと

  • 対応方法の調査
  • デプロイ済のCloudFormationのテンプレートを確認
  • ECSタスク定義の変更
  • CloudFormationのテンプレートに反映されていることを確認

対応方法の調査

2024年2月時点ではCopilotのタスク定義変更には、「YAML Patch Overrides」「CDK Overrides」の2通りの方法があります。今回は軽微な対応だったため、YAML Patchによる実装にしました。

なお、公式サイトでは「Task Definition Overrides」の方法も記載されていますが、2024年2月現在では非推奨となっております。

デプロイ済のCloudFormationのテンプレートを確認

まず、既にデプロイ済のCloudFormationのテンプレートを確認するために、AWS Copilotの svc package の下記コマンドを実行します。

AWS_PROFILE={ProfileName} copilot svc package -n api -e test --output-dir ./infrastructure

実行後 ./infrastructure 配下に api-test.stack.yml ファイルが作成されますので、今回の目的であるLogDriverの定義内容を確認します。

[実行後に作成されるファイル]
copilot svc package infrastructure

[デフォルトの設定]
api-test.stack.yml ファイルに記述されているLogDriverのOptionsを確認すると、以下のようになっています。

api-test.stack.yml(抜粋)
  ・・・
  LogConfiguration:
    LogDriver: awslogs
    Options:
        awslogs-region: !Ref AWS::Region
        awslogs-group: !Ref LogGroup
        awslogs-stream-prefix: copilot
  ・・・

ECSタスク定義の変更

cfn.patches.ymlファイルの作成

YAML Patchで既存の定義を上書きするには、 copilot/api/overrides 配下の cfn.patches.yml に上書きしたい定義を記述します。
AWS Copilotの svc override コマンドにて、対象のファイルを作成することができます。

AWS_PROFILE={ProfileName} copilot svc override

[実行後に作成されるファイル]
copilot svc override

cfn.patches.ymlファイルの編集

Yaml Patch Overridesadd オプションにて pathvalue を指定します。
path は先ほど出力した api-test.stack.yml を参照し、対象の階層まで / 区切りで指定します。他にも removereplace などのオプションがあり、削除や更新をする場合に指定します。

今回はLogDriverのOptionに awslogs-datetime-format を追加するため、以下のように記述します。

cfn.patches.yml
- op: add
  path: /Resources/TaskDefinition/Properties/ContainerDefinitions/0/LogConfiguration/Options/awslogs-datetime-format
  value: "\\[%Y-%m-%d %H:%M:%S\\]"

CloudFormationのテンプレートに反映されていることを確認

再度 svc package コマンドを実行し、作成される api-test.stack.yml を確認します。

AWS_PROFILE={ProfileName} copilot svc package -n api -e test --output-dir ./infrastructure
api-test.stack.yml
  ・・・
  LogConfiguration:
    LogDriver: awslogs
    Options:
        awslogs-region: !Ref AWS::Region
        awslogs-group: !Ref LogGroup
        awslogs-stream-prefix: copilot
        awslogs-datetime-format: "%Y-%m-%d %H:%M:%S"
  ・・・

awslogs-datetime-format: "%Y-%m-%d %H:%M:%S" がLogDriverのOptionに追加されていることを確認できました。これをデプロイすることでECSタスク定義を上書きすることができます。
infrastructure フォルダは設定ファイル確認用に作成したものなので、デプロイ前に削除しておきます。

参考文献

おわりに

公式ドキュメントの「YAML Patch Overrides」には、 svc package を利用した確認方法の記述はなく、yamlファイルに記述したコードがどのように反映されるのかを調査することにかなり時間を費やしてしまいました。作業する上で svc package コマンドは、修正したCloudFormationのテンプレートの内容をローカルで確認でき非常に便利なコマンドですので、興味のある方は是非試してみてください。

今回の対応でECSのCloudWatchの同一時刻出力ログが1つにまとまって見やすくログ収集・分析が楽になり、以前に比べるとログ管理の運用が効率的に行えるようになりました。

同様の問題を抱えている方・AWS Copilotで作成された環境のカスタマイズ方法に困っている方にとって参考になれば幸いです。

以上、H.G.M developers T.K でした。

Discussion