Blog

ECS Fargate のログを Fluent Bit で別アカウントの CloudWatch に転送する

こんにちは、サイドカーより助手席に乗りたいお姉さんです。運転免許は持っていません。

ECS Fargate で、メインのコンテナ + FireLens(Fluent Bit) のサイドカー構成で、別アカウントの CloudWatch にログを出力してみました。

FireLens とは

FireLens とは、ECSのコンテナのログを、様々な分析ツール(CloudWatch, Amazon Kinesis Data Firehose, サードパーティ製ツールなど)へ転送できる仕組みです。

コンテナ内の複数箇所に出力されたログをまとめて転送したり、逆に1つのログを複数箇所に転送したりできるため、利便性が高いです。

FireLens を用いたログ出力の基本は公式ブログに載っていますので、そちらをご参照ください。

https://aws.amazon.com/jp/blogs/news/announcing-firelens-a-new-way-to-manage-container-logs/

Fluent Bitとは

Fluent Bit は、システムのログを収集・処理してくれるツールで、非常に軽量です。

FireLens で、コンテナのログドライバーとして使うことができます。

詳細は、公式ドキュメントをご参照ください。

https://docs.fluentbit.io/manual

別アカウントへのログ転送

ECSで Fluent Bit を動かす際は CloudWatch への転送用のプラグインを使うのですが、ドキュメントを見てみると、設定の中に role_arn という項目があります。

role_arn: ARN of an IAM role to assume (for cross account access).

https://github.com/aws/amazon-cloudwatch-logs-for-fluent-bit/blob/mainline/README.md#plugin-options

for cross account access ということは、別のアカウントへも転送できるんだな~、と思ったのですが、それ以上の説明はどこにも無く、やり方が分からない!!ということでやってみました。

転送先アカウントの設定

まず、転送先のアカウントで必要な設定をしていきます。

IAMロールの作成

「転送元のアカウントから、このアカウントの CloudWatch にログを出力していいよー!」というロールを作ります。

以下の要素を含めます。

  • 信頼されたエンティティ( AssumeRolePolicyDocument )に、転送元アカウントの AssumeRole の許可を追加
    • Principal に設定されたアカウントに、このロールの権限を与えてOKだよ~という設定です
  • CloudWatch logs への書き込み許可をするポリシーをアタッチ
    • ロググループやログストリームの作成を許可します

転送元アカウントの設定

転送元アカウントの設定もしていきます。

ECSタスクロールの作成

先ほど設定した転送先アカウントのロールを、ECSタスクが引き受けられるように、転送元でもタスクロールに AssumeRole を許可するポリシーをアタッチします。

ECS タスク定義の作成

タスク定義を作ります。

今回は、プレーンなhttpdコンテナを立ち上げて、そのログを別アカウントへ転送します。

以下の値を設定していきます。それ以外はデフォルトでOKです。

  • タスクロール
    • 先ほど作成したタスクロールを選択
  • コンテナ
    • イメージURIに httpd を入力
    • 名前は何でもOK
  • ログ収集
    • AWS FireLens 経由でカスタム送信先にログをエクスポート を選択
    • オプションを設定(キーに、ドキュメントに記載されたオプションの項目を入れる)
      • Name: どこに転送するか。今回は cloudwatch です。
      • region: ロググループを作成するリージョン
      • log_group_name, log_stream_name: ロググループ名、ログストリーム名。ECSタスクのIDなどを動的に入れることができます。( https://github.com/aws/amazon-cloudwatch-logs-for-fluent-bit?tab=readme-ov-file#templating-log-group-and-stream-names )
      • auto_create_group: trueにすると、設定した名前のロググループが存在しない場合に自動で作成してくれます。
      • role_arn: ここに転送先のアカウントで作成したロールのarnを設定します!!!!
        • arn:aws:iam::${転送先アカウントのID}:role/${転送先アカウントで作成したロール名}
    • コンソールで見るとこんな感じ
    • コンソールで FireLens の設定をすると、自動的に2つ目のコンテナ( Fluent Bit が動くコンテナ)の設定の入力欄が現れますが、今回はデフォルトのままいじりませんでした。

最終的にできたタスク定義がこちらです。

タスクを起動して、ログが転送されることを確認

転送元アカウントで、先ほど作ったタスク定義でコンテナを上げます。

特にアクセス制限も必要無いので、デフォルトVPCに適当なECSクラスターを作成し、そこにタスクを1つ起動させました。

起動後しばらく待つと、コンソールのログのタブに Fluent Bit のログが出てきます。

/ecs/httpd っていうロググループに、${タスクID}っていうログストリームを作ったよ~とかそんなログが出ています。

では、転送先アカウントの方も見てみます。

コンソールから、 CloudWatch のロググループを見てみると、 /ecs/httpd があります。

ロググループを開いてみると、さっきのタスクIDでログストリームが作成されています。

ログイベントはこんな感じで出ています。

1つのログイベントに、ログのメッセージだけでなく、コンテナIDやタスクのarnまで出ているという親切設計✨

まとめ

Fluent Bit のオプションの role_arn に転送先アカウントのロールを設定することで、別アカウントへのログの転送ができました。

今回は標準出力を CloudWatch へ転送するという単純な構成でしたが、もっとカスタムした構成( Fluent Bit の設定ファイルをS3に置いたり、自前で Fluent Bit のコンテナを用意したり)でも別アカウントへの転送は可能なので、是非やってみてください^ヮ^

ニフティでは、
さまざまなプロダクトへ挑戦する
エンジニアを絶賛募集中です!
ご興味のある方は以下の採用サイトより
お気軽にご連絡ください!

ニフティに興味をお持ちの方は
キャリア登録をぜひお願いいたします!

connpassでニフティグループに
参加いただくと
イベントの
お知らせが届きます!