たそらぼ

日頃思ったこととかメモとか。

FargateでCloudWatch Logsからログをエクスポートするアイデア

fargateからAWS CLIでcreate-export-task APIを叩き、CloudWatch Logsからログをエクスポートする方法を考えてみました。

モチベーション

CloudWatch Logsに格納されたログを取り出して、別のシステムに移したいような要件があると思います。
例えば、複数システムを運用している環境で、監査用システムにログを集約したいような時などです。

CloudWatch Logsからログを取り出す方法はいくつかあります。
例えば、

  1. サブスクリプションフィルタ
  2. エクスポート機能
  3. fluentdなどの3rd party製品

ただ、どの方法も意外と面倒臭く、こういう要件に当たっている方は結構苦労している印象があります。
具体的には、

  1. ロググループあたり1個までしか使えない(2020/5現在) ため、既に埋まっていると使えない。しかもデータ部分がbase64&gzip圧縮されるので、デコードしないといけない。
  2. エクスポート後、続けて処理をするようなワークフローを作るのに、Step Functionsなどでテクいことをしないといけない。わざわざEC2を立てて、lambdaで起動/停止するのもなんか違う気がする。
  3. AWS公式の読み出しpluginがない。

バッチ処理でいいので、なんとか簡単にできないかと思っていたところ、Fargateが思い当たり、検証してみることにしました。

構成

こんな感じのことを考えています。

f:id:tasotasoso:20200515084925p:plain:w400
Fargateからエクスポート

Docker Imageを作る

エクスポートタスクを作る用のDocker Imageを作ります。

以下の公式ドキュメントを参考に、fargateからcreate-export-task APICLIから叩く作戦です。
docs.aws.amazon.com

AWS CLIを使う分には、公式でイメージ(AWS CLI v2 Docker image | AWS Developer Blog)を公開してくれていますが、個人的にpythonのイメージで自作した方がやりやすかったので、そちらで行きます。

そうすると、以下のようなDockerfileになります。

FROM python:3.7-alpine                                                                                                                                    
RUN pip3 install awscli

CMD aws logs create-export-task --task-name "my-log-group-09-10-2015" --log-group-name "my-log-group" --from 1441490400000 --to 1441495000000 --destination "my-exported-logs" --destination-prefix "export-task-output"


なお、create-export-task APIの仕様は、下記のドキュメントにあります。注意点としては、エクスポートするログのタイムスタンプを、ミリ秒単位のUNIXタイムで書くのが厄介です。
docs.aws.amazon.com


今回は時間をdocker fileに決め打ちで書いていますが、dateコマンドで動的に取得して取れると良いです。なお、ミリ秒単位のUNIXタイムは下記で取得できます。

date +%s%3

fargateにはIAMロールで権限を設定する

create-export-task APIを実行するには、実行側に、CloudWatch LogsとS3のフルアクセスが必要なので、タスクロールとして使用するIAMロールにつけておきます。
後はpushしたDocker imageをfargateにpullしてタスクとして実行するだけです。

fargateを使うのが初めての方は、初心者向けのサイト等を参考に設定してみてください。
dev.classmethod.jp
docker imageをビルドして、ECRにpushしておくのも忘れずに。


スケジューリング

タスクはECSの機能で一貫して、cron方式でスケジューリングできるようです。この機能でスケジュールしておけば、簡単にバッチ処理化できそうです。
docs.aws.amazon.com
qiita.com

感想

この方法であれば、指定の時間になればFargateが勝手に起きてくれてエクスポートして落ちてくれるので、めっちゃ楽ですし、安く済みます。
Lambdaを駆使して頑張ったり、事故ったりする必要もなさげです。
EC2を立てる程ではないけど、Lambdaのカバー範囲より少し長めの時間がかかる処理って、とても大変だなぁと痛感しました。Fargateがあってくれて本当によかったです。