こんにちは、サイドカーより助手席に乗りたいお姉さんです。運転免許は持っていません。
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 という項目があります。
https://github.com/aws/amazon-cloudwatch-logs-for-fluent-bit/blob/mainline/README.md#plugin-options
role_arn
: ARN of an IAM role to assume (for cross account access).
for cross account access
ということは、別のアカウントへも転送できるんだな~、と思ったのですが、それ以上の説明はどこにも無く、やり方が分からない!!ということでやってみました。
転送先アカウントの設定
まず、転送先のアカウントで必要な設定をしていきます。
IAMロールの作成
「転送元のアカウントから、このアカウントの CloudWatch にログを出力していいよー!」というロールを作ります。
以下の要素を含めます。
- 信頼されたエンティティ( AssumeRolePolicyDocument )に、転送元アカウントの AssumeRole の許可を追加
- Principal に設定されたアカウントに、このロールの権限を与えてOKだよ~という設定です
- CloudWatch logs への書き込み許可をするポリシーをアタッチ
- ロググループやログストリームの作成を許可します
転送元アカウントの設定
転送元アカウントの設定もしていきます。
ECSタスクロールの作成
先ほど設定した転送先アカウントのロールを、ECSタスクが引き受けられるように、転送元でもタスクロールに AssumeRole を許可するポリシーをアタッチします。
ECS タスク定義の作成
タスク定義を作ります。
今回は、プレーンなhttpdコンテナを立ち上げて、そのログを別アカウントへ転送します。
以下の値を設定していきます。それ以外はデフォルトでOKです。
- タスクロール
- 先ほど作成したタスクロールを選択
- コンテナ
- イメージURIに
httpd
を入力 - 名前は何でもOK
- イメージURIに
- ログ収集
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 のコンテナを用意したり)でも別アカウントへの転送は可能なので、是非やってみてください^ヮ^