6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ECS Managed Instances × FireLensでログをS3に保存してみた

Last updated at Posted at 2025-10-21

はじめに

先日、とあるスライドを読み返して「そういえばFireLensって聞いたことあるけど、触ったことないなぁ」と思ったのと、先日のアップデートでECSマネージドインスタンスが発表されてたなと思い、両方まとめてキャッチアップすることにしました。

FireLensとは

スライドを見るのが一番早いですが、簡単にまとめます。

FireLensはECS Task上で実行されるアプリケーションのログを収集する手段の一つです。通常はCloudWatch Logsで事足りますが、システムが大規模で、ログの量が多い場合はCloudWatch Logsの取り込み料金が高額になる可能性があります。

そのためログの活用方法次第で、CloudWatch LogsではなくS3等に保存するというのも選択肢になります。

FireLensはCloudWatch Logs以外のAWSサービス(S3やOpenSearchなど)やSaaS (Splunkなど)へのログ転送が可能となるログルーティングの仕組みです。

FluentdまたはFluent BitというOSSをサイドカーパターンで配置することで、CloudWatch Logs以外へのログ転送が可能となります。ちなみに、AWSではFluent Bitの利用を推奨しています。

AWS は、CloudWatch Logs と Firehose の両方のプラグインに Fluent Bit イメージを提供します。Fluent Bit は、リソース使用率が Fluentd よりも低いため、ログルーターとして使用することをお勧めします。

ECSマネージドインスタンスとは

これまで、ECSのデータプレーンとして利用できるものはFargateかEC2の2択でした(ECS Anywhereは別)。AWS管理かユーザー管理かで選択することになっていましたが、今回登場したマネージドインスタンスは中間に当たる仕組みで、EC2で起動はするものの、セキュリティパッチ当てなどがAWS管理となり、本来ユーザーの責務であったことをAWSにて行ってくれるものになります。
Fargateでは実現できない高性能なEC2やGPUインスタンスを使いたけど、管理はしたくない...そんなニーズに応えるサービスです。

試してみる

構成

今回作成する構成はこちらです。図には記載していませんが、ECSで動かすコンテナはマネージドインスタンスを利用します。
構成.jpg

S3バケットを作成する

まずはログの保存先となるS3バケットを作成します。
バケットタイプは「汎用」を選び、バケット名は任意の名前にします。他の設定はデフォルトにしておきます。

任意の名前でOKですが、全世界で一意な名前である必要があります。ご自身の名前や日付などを入れることで一意になりやすいです。

S3バケット作成.png

ECS用のVPCを作成する

続いて、ECSのコンテナを動作させるためのVPCを作成します。今回は検証用ということでパブリックサブネットを1つ、インターネットゲートウェイを作成します。

スクリーンショット 2025-10-15 23.16.52.png
スクリーンショット 2025-10-15 23.17.23.png

VPC作成後、パブリックサブネットで「パブリックIPv4アドレスの自動割り当てを有効化」します。
※今回、検証用ということでパブリックサブネットにECS Taskを配置します。

スクリーンショット 2025-10-16 23.22.09.png

ECSクラスターを作成する

続いて、ECSクラスターを作成していきます。コンピューティングキャパシティは「Fargateインスタンスとマネージドインスタンス」を選択します。その下でインスタンスプロファイルとインフラストラクチャロールの設定が必要になります。今回は新規作成が必要になるので手順に従って作成していきます。

スクリーンショット 2025-10-15 23.18.14.png

インスタンスプロファイルの作成

まずはこちらのドキュメントを参照しながらインスタンスプロファイルを作成します。

インスタンスプロファイルをマネコンから作成することはできなさそうなため、AWS CLIで作成しています。

まずは信頼ポリシーとなるJSONファイルを用意します。

ecsInstanceRole-trust-policy.json
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": { "Service": "ec2.amazonaws.com"},
      "Action": "sts:AssumeRole"
    }
  ]
}

このJSONファイルを作成後、IAMロールを作成します。

aws iam create-role \ 
      --role-name ecsInstanceRole \
      --assume-role-policy-document file://ecsInstanceRole-trust-policy.json

こちらのIAMロールにマネージドポリシーをアタッチします。

aws iam attach-role-policy \
      --role-name ecsInstanceRole \
      --policy-arn arn:aws:iam::aws:policy/AmazonECSInstanceRolePolicyForManagedInstances

その後、インスタンスプロファイルを作成します。

aws iam create-instance-profile --instance-profile-name ecsInstanceRole

最後に、インスタンスプロファイルにロールを追加します。

aws iam add-role-to-instance-profile \
   --instance-profile-name ecsInstanceRole \
   --role-name ecsInstanceRole 

インスタンスプロファイルが作成できているか確認します。

aws iam get-instance-profile --instance-profile-name ecsInstanceRole 

これでインスタンスプロファイルは作成完了です。

インフラストラクチャロールの作成

続いてインフラストラクチャロールを作成します。

インスタンスプロファイルと同じように、信頼ポリシーを記載したJSONファイルを作成します。

ecs-infrastructure-trust-policy.json
{
  "Version": "2012-10-17", 
  "Statement": [ 
    {
      "Sid": "AllowAccessToECSForInfrastructureManagement", 
      "Effect": "Allow", 
      "Principal": {
        "Service": "ecs.amazonaws.com" 
      }, 
      "Action": "sts:AssumeRole" 
    } 
  ] 
}

IAMロールを作成します。

aws iam create-role \
      --role-name ecsInfrastructureRole \
      --assume-role-policy-document file://ecs-infrastructure-trust-policy.json

IAMポリシーをアタッチします。

aws iam attach-role-policy \
      --role-name ecsInfrastructureRole \
      --policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSInfrastructureRolePolicyForVolumes
aws iam attach-role-policy \
      --role-name ecsInfrastructureRole \
      --policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSInfrastructureRolePolicyForServiceConnectTransportLayerSecurity

ここでは2つIAMポリシーをアタッチしていますが、これだけでは動作しませんでした。(詳細は後述します。)

ユースケース(VPC Latticeを利用する場合)によってはAmazonECSInfrastructureRolePolicyForServiceConnectTransportLayerSecurityの代わりにAmazonECSInfrastructureRolePolicyForVpcLatticeをアタッチする必要がありそうです。

この後、インフラストラクチャロールをECSで利用するために、操作するユーザにはiam:PassRoleの権限が必要になります。

VPCの設定

続いてVPCの設定を行います。先ほど作成したVPC情報を入力していきます。サブネットは作成したパブリックサブネットを選択します。
セキュリティグループは後からでも修正可能ですが、自端末のIPアドレスからのHTTPアクセスを許可するインバウンドルールを設定します。(後ほどnginxコンテナを立ち上げてアクセスするためHTTPを許可しています)
スクリーンショット 2025-10-16 22.06.49.png

改めて設定する

ここまでで必要な設定は完了し、クラスターを作成しようとしたのですが、エラーが発生しました。
スクリーンショット 2025-10-16 22.01.47.png

スクリーンショット 2025-10-16 22.14.17.png

エラー内容.txt
Resource handler returned message: "Invalid request provided: You are not authorized to perform this operation. User: arn:aws:sts::【AWSアカウントID】:assumed-role/ecsInfrastructureRole/ECSManagedInstances is not authorized to perform: ec2:DescribeSubnets because no identity-based policy allows the ec2:DescribeSubnets action (Service: Ec2, Status Code: 403, Request ID: 3a128192-2c2a-4753-9fca-da3cfbd8cf7a) (SDK Attempt Count: 1)" (RequestToken: 99ff4c5f-7d0b-7f07-a4ee-b31e54b4d9c3, HandlerErrorCode: InvalidRequest)

どうやらインフラストラクチャロール(ecsInfrastructureRole)にec2:DescribeSubnetsの権限がないとのことです。
ec2:DescribeSubnetsが含まれているAmazonEC2ContainerServiceRoleをアタッチしてみました。

aws iam attach-role-policy \
      --role-name ecsInfrastructureRole \
      --policy-arn arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceRole      

今度は別のエラーでec2:CreateLaunchTemplateが不足しているとエラーになりました。マネージドインスタンスとはいえ、EC2が動いていますのでECS on EC2で必要な権限は一通り必要だと思われます。

本番では推奨されませんが、検証ということでAmazonECS_FullAccess、AmazonEC2FullAccessをつけることにしました。

aws iam attach-role-policy \
      --role-name ecsInfrastructureRole \
      --policy-arn arn:aws:iam::aws:policy/AmazonECS_FullAccess      
aws iam attach-role-policy \
      --role-name ecsInfrastructureRole \
      --policy-arn arn:aws:iam::aws:policy/AmazonEC2FullAccess    

これらのポリシーをアタッチすることで無事にECSクラスターの作成が完了しました。

ECSタスク定義を作成する

起動タイプは「マネージドインスタンス」を選択します。ネットワークモードは今回「host」を選択しています。

スクリーンショット 2025-10-16 23.34.55.png

コンテナ1ではnginx:latestからコンテナイメージを取得し、起動するためのイメージURIを入力します。
スクリーンショット 2025-10-16 22.37.47.png

ログ収集コンテナ

ログ記録では、ログ収集の使用にチェックを入れた上で、「AWS FireLens経由でS3にログをエクスポートする」を選択します。
キーと値は以下のように設定します。(Nameはデフォルトでs3が入ると思います)

キー
region (S3バケットがあるリージョン、ここではap-northeast-1)
bucket (作成したS3バケット名)
total_file_size 1M(デフォルト)
upload_timeout 1m(デフォルト)
use_put_object On

スクリーンショット 2025-10-16 22.44.11.png

今回は設定していませんが、必要に応じてs3_key_formatを設定することで、S3のパス形式を指定可能です。例えばAthena等で分析を行う際はs3_key_formatの設定もしておいた方が良いでしょう。

ログルーター(FireLens)自体のコンテナも設定します。このコンテナのログ収集はCloudWatchにします。
スクリーンショット 2025-10-16 22.45.38.png

ここまででタスク定義は作成完了ですが、作成されたECSタスクロール(ecsTaskExecutionRole)にはS3にオブジェクトをPUTする権限がついていないのでAmazonS3FullAccess付与します。ここも本来は権限を絞った方が良いです。
スクリーンショット 2025-10-16 22.48.44.png

タスクを起動する

ECSサービス経由で作成します。
スクリーンショット 2025-10-16 22.59.47.png

タスク定義ファミリーは作成したタスク定義を選択します。
スクリーンショット 2025-10-16 23.00.44.png

キャパシティープロバイダ戦略を選択しないと、マネージドインスタンスでは起動出来なさそうです。
ネットワーキングはクラスター作成時の設定が入っているので、変更不要です。

必要なタスク数を1にした上で、いざ起動!

動作確認

IPアドレスはEC2のコンソールから確認します。(ネットワークモードがawsvpcではECSタスクにはパブリックIPが振られていないようでした(=ネットワークモードをhostにした理由))

ECSクラスター作成時、「ECSのデフォルトを使用」を選択すると、画像の通りm7a.mediumインスタンスで立ち上がりました。

スクリーンショット 2025-10-16 23.36.27.png

このIPにHTTPでアクセスすると、nginxの画面が表示されます。

スクリーンショット 2025-10-16 23.37.28.png

そしてS3のコンソールに行くとログが記録されていることを確認できます。

スクリーンショット 2025-10-16 23.39.42.png

ログもしっかり記録されています。

{"date":"2025-10-16T14:34:09.782489Z","log":"【送信元IP】 - - [16/Oct/2025:14:34:09 +0000] \"GET / HTTP/1.1\" 200 615 \"-\" \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36\" \"-\"","container_id":"9774889e8bfc47488ab6acd664e9f88e-2531612879","container_name":"nginx","source":"stdout","ecs_cluster":"alchemy-ecs-cluster","ecs_task_arn":"arn:aws:ecs:ap-northeast-1:124878107919:task/alchemy-ecs-cluster/9774889e8bfc47488ab6acd664e9f88e","ecs_task_definition":"alchemy-ecs-task-definition:3"}

補足

これまではAWS for Fluent Bit自体は、Fluent Bit 1.9.10までしかサポートされていなかったようですが、AWS for Fluent Bit 3.0.0が最近(2025/10/14)リリースされ、Fluent Bit 4.1.1をサポートしているようです!

まとめ

初めてFireLens/Fluent Bitを触ってみましたが、想像していたよりも容易に設定ができました。また、マネージドインスタンスでのECSタスク起動も経験できました。今後ECSでコンテナを立ち上げる際の参考にしたいと思います。

参考

記事を書くきっかけになったスライド

インフラストラクチャロールとインスタンスプロファイル関連

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?