これは何?

案件にて、構築したEC2(Amazon Linux 2023)内のログを別アカウントのS3バケットに転送する要件があり、Fluentdを用いて設定をしました。
手順と設定ファイルの中身を記載します。

要件

構築したAmazon Linux 2023内のApacheアクセスログを別アカウントのS3バケットに転送します。
※下記の{other_account_s3_bucket}が別アカウントのS3バケット名

種別 対象 保存先
Apacheアクセスログ /var/log/httpd/access_log s3://{other_account_s3_bucket}/access_log/xx

構成図

バージョン

こちらのドキュメントによると、Amazon Linux 2023には、fluent-package 5が対応しているとのこと。
LTS版の方が長期サポートなどのメリットがありそうなのでこちらを導入します。

手順

IAMロール設定

こちらのドキュメントを参考に、アカウントAのAmazon EC2インスタンスに別のアカウント (アカウントB) のバケットへのアクセス権限を付与します。
今回だとアカウントBが別アカウント、アカウントAが構築対象アカウントです。
下記手順で設定します。

  • 別アカウント(アカウントB)にてIAMロール作成 & ロールのARNを取得
  • 構築対象アカウント(アカウントA)にて、別のロール(インスタンスプロファイル)を作成し、インスタンスにアタッチする
  • Amazon EC2インスタンスにて、CLI設定ファイルにロールのプロファイルを設定

別アカウントにてIAMロール作成 & ロールの ARN を取得

別アカウント(アカウントB)にて、構築対象アカウント(アカウントA)がAssumeRole(ロール引き受け)できるようなIAMロールを作成します。
そのIAMロールのARNを控えておきます。
※ポリシー設定は割愛します。

構築対象アカウントにてEC2インスタンスプロファイル設定

IAMロールを作成し、EC2にインスタンスプロファイルとしてアタッチします。

信頼関係

EC2用のIAMロールなので、信頼関係は次のように設定します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Principal": {
                "Service": "ec2.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
許可ポリシー

下記の通りポリシーを作成し、IAMロールにアタッチします。
他に必要なポリシーがあれば別途アタッチします。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "${iam_role_arn}" // 別アカウント(アカウントB)にて作成したIAMロールのARN
        }
    ]
}
CLI 設定ファイルにロールのプロファイルを設定

Fluentdのログ転送処理について、rootユーザで実行されるように設定をする予定です(後述)。
そのため、rootユーザのCLI設定ファイルにロールのプロファイルを設定します。

  • /rootに.awsディレクトリ作成
# pwd
/root
# mkdir ~/.aws/
# ls -la
total 24
dr-xr-x---.  4 root root 136 Jul 27 22:07 .
dr-xr-xr-x. 18 root root 237 Jul 20 02:38 ..
drwxr-xr-x.  2 root root   6 Jul 27 22:07 .aws
(略)
  • configファイル作成
# cd .aws
# vi config
# cat config 
[profile iret-web11-role]
role_arn = {別アカウント(アカウントB)で作成したIAMロールのARN}

credential_source = Ec2InstanceMetadata
  • インスタンスプロファイルがロールを引き受けることができることを確認
  • Amazon S3バケットへのアクセスを検証
# aws sts get-caller-identity --profile iret-web11-role
{
  // "UserId","Account","Arn"が出力されるので、内容が想定通りになっているかどうか確認する
  // 別アカウント(アカウントB)で作成したIAMロールの情報が表示されるはず
}
# aws s3 ls s3://{other_account_s3_bucket}/access_log/ --profile iret-web11-role
              PRE AWSLogs/

Fluentdインストール

こちらのドキュメントを参考にしてインストールしていきます。

  • インストール実行
# curl -fsSL https://toolbelt.treasuredata.com/sh/install-amazon2023-fluent-package5-lts.sh | sh
==============================
 fluent-package Installation Script 
==============================
This script requires superuser access to install rpm packages.
You will be prompted for your password by sudo.
Fluentd Project                                                                                                                                    3.1 MB/s | 314 kB     00:00    
Last metadata expiration check: 0:00:01 ago on Sat Jul 27 22:12:36 2024.
Dependencies resolved.
===================================================================================================================================================================================
 Package                                    Architecture                        Version                                       Repository                                      Size
===================================================================================================================================================================================
Installing:
 fluent-package                             aarch64                             5.0.4-1.amzn2023                              fluent-package-lts                              14 M

Transaction Summary
===================================================================================================================================================================================
Install  1 Package

Total download size: 14 M
Installed size: 90 M
Downloading Packages:
fluent-package-5.0.4-1.amzn2023.aarch64.rpm                                                                                                        6.4 MB/s |  14 MB     00:02    
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                                                                              6.4 MB/s |  14 MB     00:02     
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                                                                                                                           1/1 
  Running scriptlet: fluent-package-5.0.4-1.amzn2023.aarch64                                                                                                                   1/1 
  Installing       : fluent-package-5.0.4-1.amzn2023.aarch64                                                                                                                   1/1 
  Running scriptlet: fluent-package-5.0.4-1.amzn2023.aarch64                                                                                                                   1/1 
Failed to get unit file state for td-agent.service: No such file or directory
inactive

  Verifying        : fluent-package-5.0.4-1.amzn2023.aarch64                                                                                                                   1/1 

Installed:
  fluent-package-5.0.4-1.amzn2023.aarch64                                                                                                                                          

Complete!

Installation completed. Happy Logging!
  • デーモン起動
# systemctl start fluentd.service
# systemctl status fluentd.service
● fluentd.service - fluentd: All in one package of Fluentd
     Loaded: loaded (/usr/lib/systemd/system/fluentd.service; disabled; preset: disabled)
     Active: active (running) since Sat 2024-07-27 22:13:25 JST; 8s ago
       Docs: https://docs.fluentd.org/
    Process: 25435 ExecStart=/opt/fluent/bin/fluentd --log $FLUENT_PACKAGE_LOG_FILE --daemon /var/run/fluent/fluentd.pid $FLUENT_PACKAGE_OPTIONS (code=exited, status=0/SUCCESS)
   Main PID: 25441 (fluentd)
      Tasks: 9 (limit: 406)
     Memory: 87.1M
        CPU: 1.838s
     CGroup: /system.slice/fluentd.service
             ├─25441 /opt/fluent/bin/ruby /opt/fluent/bin/fluentd --log /var/log/fluent/fluentd.log --daemon /var/run/fluent/fluentd.pid
             └─25444 /opt/fluent/bin/ruby -Eascii-8bit:ascii-8bit /opt/fluent/bin/fluentd --log /var/log/fluent/fluentd.log --daemon /var/run/fluent/fluentd.pid --under-supervisor

Jul 27 22:13:23 sekiguchi-test systemd[1]: Starting fluentd.service - fluentd: All in one package of Fluentd...
Jul 27 22:13:25 sekiguchi-test systemd[1]: Started fluentd.service - fluentd: All in one package of Fluentd.
  • systemd設定 & rootユーザー実行設定
    • systemd は/etc/systemd/system/配下のファイルを参照するため、/usr/lib/systemd/system/fluentd.service/etc/systemd/system配下にコピーし、/etc/systemd/system/fluentd.serviceの方を編集する
      • /etc/systemd/system/fluentd.service内のユーザー・グループの指定を、rootに変更
# cp -a /usr/lib/systemd/system/fluentd.service /etc/systemd/system
# ls -la /etc/systemd/system/fluentd.service
-rw-r--r--. 1 root root 1028 Jul  8 13:18 /etc/systemd/system/fluentd.service
# vi /etc/systemd/system/fluentd.service
# diff /usr/lib/systemd/system/fluentd.service /etc/systemd/system/fluentd.service
8,9c8,9
< User=fluentd
< Group=fluentd
---
> User=root
> Group=root

  • デーモンリロードして再起動
  • rootで起動していることを確認
# systemctl daemon-reload
# systemctl restart fluentd
# systemctl status fluentd.service
● fluentd.service - fluentd: All in one package of Fluentd
     Loaded: loaded (/etc/systemd/system/fluentd.service; disabled; preset: disabled)
     Active: active (running) since Sat 2024-07-27 22:19:40 JST; 6s ago
       Docs: https://docs.fluentd.org/
    Process: 25694 ExecStart=/opt/fluent/bin/fluentd --log $FLUENT_PACKAGE_LOG_FILE --daemon /var/run/fluent/fluentd.pid $FLUENT_PACKAGE_OPTIONS (code=exited, status=0/SUCCESS)
   Main PID: 25701 (fluentd)
      Tasks: 9 (limit: 406)
     Memory: 77.5M
        CPU: 1.701s
     CGroup: /system.slice/fluentd.service
             ├─25701 /opt/fluent/bin/ruby /opt/fluent/bin/fluentd --log /var/log/fluent/fluentd.log --daemon /var/run/fluent/fluentd.pid
             └─25704 /opt/fluent/bin/ruby -Eascii-8bit:ascii-8bit /opt/fluent/bin/fluentd --log /var/log/fluent/fluentd.log --daemon /var/run/fluent/fluentd.pid --under-supervisor

Jul 27 22:19:39 sekiguchi-test systemd[1]: Starting fluentd.service - fluentd: All in one package of Fluentd...
Jul 27 22:19:40 sekiguchi-test systemd[1]: Started fluentd.service - fluentd: All in one package of Fluentd.
  • S3用のプラグインはデフォルトでインストールされている
    • 一応、入っていることを確認した
# fluent-gem list | grep s3
aws-sdk-s3 (1.129.0)
fluent-plugin-s3 (1.7.2)

Fluentd設定ファイル作成

ログ集約の各種設定、および送付先S3について設定ファイルを作成して指定します。
設定ファイルについては下記の点に注意

  • デフォルト設定ファイルは退避しておくこと
    • デフォルトの/etc/fluent/fluentd.confは色々といらない設定が入ってたりするので、退避しておくのが良い
  • s3_object_key_formatの指定方法
    • ファイル名が一意になるよう設定する
    • uuid_flushを入れることでfluentdが一意のUUIを発行してくれるため、ファイル名が一意になる

それでは/etc/fluent/fluentd.confファイルを下記のとおり設定していきます。
設定値について、自分なりに整理してみました。

  • sourceディレクティブ
    • @type:プラグインを指定。今回はin_tailプラグイン
      • in_tailプラグインについてはこちらを参照
    • path:S3に保存するログファイルのパス
    • tag:matchディレクティブが拾うためのタグ指定
    • pos_file:pathで指定したファイルの何行目までを読み取った(tailした)かを記録しておくためのposファイルのパス
  • matchディレクティブ:どの集約ファイルを対象とするか、tagづけされた名前を指定
    • @type:プラグインを指定。今回はS3プラグイン
    • s3_bucket:S3バケット名
    • s3_region:S3バケットのあるリージョン
    • s3_object_key_format:S3にPutする際のファイルパス
    • path:S3バケット配下のプレフィックスパス
    • time_slice_format:時間指定する際のフォーマット
    • buffer time:buffer句を設定した場合、ログを即時的ではなく指定した期間貯めた上で転送する
      • timeを指定した場合はtimekey(秒)で指定した期間貯めてから、転送を行う
      • timekey_wait:フラッシュ遅延期間を指定。ここで指定した秒数処理を待ってから転送される。
      • flush_at_shutdown:trueにした場合、バッファ(溜め込み)を行なっている間にシャットダウンされた場合、そのバッファ分を転送して失われないようにする
    • assume_role_credentials:使用するIAMロール情報を設定
      • role_arn:IAMロールのARNを入力
        • 今回は別アカウント(アカウントB)にて作成したIAMロールのARN
      • role_session_name:ロールのセッションの名前
        • 多分なんでも良い。セッション名を指定するとログとか追いやすいとか?
<source>
  @type tail
  path /var/log/httpd/access_log
  tag os.httpd_log.access_log
  pos_file /var/log/fluent/httpd-access.pos
  format none
</source>

<match os.httpd_log.access_log>
  @type s3
  s3_bucket {other_account_s3_bucket} // 転送先のS3バケット名を設定
  s3_region ap-northeast-1
  s3_object_key_format %{path}%{time_slice}_%{uuid_flush}.%{file_extension}
  path access_log/
  time_slice_format %Y/%m/%d/%H/%Y%m%d%H_os_access_log_iret-web11
  <buffer time>
    @type file
    path /var/log/fluent/buffer/access_log
    timekey 3600
    timekey_wait 600
    flush_at_shutdown true
  </buffer>
  <assume_role_credentials>
    role_arn {別アカウント(アカウントB)で作成したIAMロールのARN}
    role_session_name iret-web11-role
  </assume_role_credentials>
</match>

ログがS3に転送されたことを確認

しばらく待った後、Apacheアクセスログが指定したS3バケットに転送されていることが確認できました。

# aws s3 ls s3://{other_account_s3_bucket}/access_log/2024/07/27/23/ --profile iret-web11-role
2024-07-27 23:16:03        297 2024072723_os_access_log_iret-web11_0e1c2c6a-d001-4ba6-a7e8-8bd253fe299b.gz
2024-07-27 23:07:59        355 2024072723_os_access_log_iret-web11_708af4ba-9db6-40ff-8b03-c140fdbe770f.gz
2024-07-27 23:11:03        222 2024072723_os_access_log_iret-web11_f63ad953-f075-462f-b6a2-ebe5edecad20.gz

注意点

in_tailプラグインはtail -f コマンドと同じような感じで転送対象のファイルの末尾を見ています。
そのため、転送対象ファイルが追記されない限り、ファイル転送を実行してくれません。
Fluentd設定完了するまでログ出力止めておく、みたいなことをしていた場合、いざ設定完了しても出力されないので注意です。
私は別のログファイルでその事象が発生し、解決に時間を取られました…

最後に

Amazon Linux 2023にFluentdを導入する手順を紹介しました。
参考にしていただければ幸いです。