Fargateスケジュールタスクがたまに実行されないことがある


Fargateスケジュールタスクとは

Amazon EventBridgeのスケジューラを使って、ECS(Fargate)のタスクを定期実行する仕組みです。

[参考] https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/userguide/scheduled_tasks.html

結論

2021年10月現在、タスク起動時に環境変数をS3から取得するようにタスク定義を設定している場合は、タスクの実行に失敗することがあります。
(今後AWS側に修正してもらえる可能性はあります。)

なお、調査の余地がありますが、
VPCエンドポイント・NAT・パブリックIPの有無などの環境の違いで発生頻度に差がある可能性があります。

詳細

一つずつ、原因を探っていきます。

RunTaskが実行されているか確認

CloudTrailにてRunTaskイベントを確認

CloudTrailをオンにしている場合、各APIの実行履歴を取得できます。
コンソール画面の場合、イベント履歴からイベント名「RunTask」でフィルターしましょう。
もしイベントが記録されている場合、タスク自体は起動されたことがわかります。

CloudWatchメトリクスでInvocationを確認

EventBridgeのメトリクスで、スケジュールタスクが呼ばれていたかどうかを確認します。
こちらも、Invocationsが記録されている場合、タスク自体は起動されたことがわかります。

タスク停止理由をログに記録する

ここまで、特にアプリケーションが実行されなかった理由は見当たりませんでした。
しかし、スケジュールタスクのアプリケーションは間違いなく実行されていません。
つまり、タスクを起動したが、アプリケーションの実行前に停止したことが考えられます。

そこで、タスク停止ログを記録するためのCloudWatchLogsを作成します。

CloudFormationにてタスク停止ログを記録する仕組みを構築

以下のCloudFormationテンプレートを使用して仕組みを構築します。
https://github.com/aws-samples/amazon-ecs-stopped-tasks-cwlogs

以下の記事も参考にさせていただきました。(ありがとうございます!)
https://dev.classmethod.jp/articles/tsnote-ecs-how-can-i-store-the-reason-for-stopping-ecs-tasks-in-cloudwatch-logs/

タスク停止理由にてエラーログを確認

停止ログが記録されるようになったので、実際に確認します。
すると…

ResourceInitializationError: failed to download env files: file download command: non empty error stream: RequestCanceled: request context canceled caused by: context deadline exceeded

停止理由(stoppedReason)にてエラーメッセージを確認できました。

タスク起動時に環境変数をS3から取得するように設定しており、稀に取得できないことがあるようです。

コンソール画面でのタスク定義箇所はこちらです。

タスク定義ファイルでいうと以下の部分が該当します。

"containerDefinitions": [
    {
      "dnsSearchDomains": null,
      "environmentFiles": [
        {
          "value": "arn:aws:s3:::xxxxxxxxxx/.env",
          "type": "s3"
        }
      ],

...

備考

2021年10月23日現在、以下のIssueが発行されており、続報が待たれています。
https://github.com/aws/aws-cli/issues/6470