クロスアカウントアクセスを用いてCloudTrailのイベント履歴を別アカウントのS3バケットに集約してみた

クロスアカウントアクセスを用いてCloudTrailのイベント履歴を別アカウントのS3バケットに集約してみた

2025.09.12

はじめに

みなさんこんにちは、クラウド事業本部コンサルティング部の浅野です。
Organizationsを使用していなくてもCloudTrailのイベント履歴ログを単一アカウントのS3バケットに集約する方法がいくつかあります。

S3のレプリケーションを用いて共有する方法は以下のブログが参考になります。

https://dev.classmethod.jp/articles/cloudtrail-aggregation-without-organizations-s3-replication/

今回はシンプルにクロスアカウントアクセス設定を用いてS3バケットに別アカウントからイベント履歴を保存する設定を行ってみたいと思います。

こちらの特徴として証跡を作成したアカウントのS3バケットにはイベント履歴が保管されないのでコストはカットされますが、参照するときには保管しているアカウントの管理者に問い合わせる必要があることですね。

公式ドキュメントにも設定方法が載っておりますので、基本的にはこちらの手順に沿っていく形になります。

https://docs.aws.amazon.com/ja_jp/awscloudtrail/latest/userguide/cloudtrail-receive-logs-from-multiple-accounts.html

構成

今回はCloudTrailの証跡をアカウントAとB両方に作成し、どちらのイベント履歴もアカウントBのS3バケットに保管します。

今回はデータ保管時にアカウントBのKMSキーを用いてどちらのログも暗号化します。

2025-09-12-cloudtrail-crossaccount-s3-01

やってみた

1. アカウントBでCloudTrail証跡、S3バケット、KMSキーを作成する。

まずはアカウントB(集約アカウント)の「CloudTrail」の証跡から作成します。不要な場合はS3バケット,KMSキーを個別に作成してください。

コンソール画面から「証跡の作成」を選択し以下の情報を入力します。

  • 証跡名: 適宜設定
  • ストレージの場所: 今回は新規でS3バケットを作成します。画像のようにバケット名はサジェストしてくれます。
  • ログファイルのSSE-KMS暗号化: 有効
  • カスタマー管理のAWS KMSキー: 新規作成し「エイリアス」を入力します。

2025-09-12-cloudtrail-crossaccount-s3-02

今回はログイベントの選択として以下2つを保管してみます。どのイベントでもやることは変わりません。

  • 管理イベント
  • データイベント(S3)

2025-09-12-cloudtrail-crossaccount-s3-03

2025-09-12-cloudtrail-crossaccount-s3-04

2025-09-12-cloudtrail-crossaccount-s3-05

以下のように無事証跡が作成されました。
この時点でS3バケットの作成とカスタマー管理型KMSキーも作成されます。

2025-09-12-cloudtrail-crossaccount-s3-06

2. S3バケットポリシーの編集

証跡を作成する際に自動で作成されたS3バケットのバケットポリシーは以下の様になっています。

変更前
			
			{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AWSCloudTrailAclCheck20150319-75ee7724-73e3-4b63-abee-7f8a7169f262",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudtrail.amazonaws.com"
            },
            "Action": "s3:GetBucketAcl",
            "Resource": "arn:aws:s3:::aws-cloudtrail-logs-{アカウントB ID}-88910232",
            "Condition": {
                "StringEquals": {
                    "AWS:SourceArn": "arn:aws:cloudtrail:ap-northeast-1:{アカウントB ID}:trail/demo-trail"
                }
            }
        },
        {
            "Sid": "AWSCloudTrailWrite20150319-4b4b0793-e385-4f52-9e2a-0ffe49058300",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudtrail.amazonaws.com"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::aws-cloudtrail-logs-{アカウントB ID}-88910232/AWSLogs/{アカウントB ID}/*",
            "Condition": {
                "StringEquals": {
                    "AWS:SourceArn": "arn:aws:cloudtrail:ap-northeast-1:{アカウントB ID}:trail/demo-trail",
                    "s3:x-amz-acl": "bucket-owner-full-control"
                }
            }
        }
    ]
}

		

アカウントAの証跡からこのバケットにアクセスできるようにポリシーの内容を編集しましょう。
CloudTrailの証跡名はどちらも同じ「demo-trail」に合わせる予定です。適宜変更してください。
基本的にアカウントが増えると、こちらの内容を適宜編集する必要があります

変更後
			
			{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AWSCloudTrailAclCheck20150319-75ee7724-73e3-4b63-abee-7f8a7169f262",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudtrail.amazonaws.com"
            },
            "Action": "s3:GetBucketAcl",
            "Resource": "arn:aws:s3:::aws-cloudtrail-logs-{アカウントB ID}-88910232",
            "Condition": {
                "StringEquals": {
                    "AWS:SourceArn": [
                        "arn:aws:cloudtrail:ap-northeast-1:{アカウントB ID}:trail/demo-trail",
                        "arn:aws:cloudtrail:ap-northeast-1:{アカウントA ID}:trail/demo-trail"
                    ]
                }
            }
        },
        {
            "Sid": "AWSCloudTrailWrite20150319-4b4b0793-e385-4f52-9e2a-0ffe49058300",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudtrail.amazonaws.com"
            },
            "Action": "s3:PutObject",
            "Resource": [
                "arn:aws:s3:::aws-cloudtrail-logs-{アカウントB ID}-88910232/AWSLogs/{アカウントB ID}/*",
                "arn:aws:s3:::aws-cloudtrail-logs-{アカウントB ID}-88910232/AWSLogs/{アカウントA ID}/*"
            ],
            "Condition": {
                "StringEquals": {
                    "s3:x-amz-acl": "bucket-owner-full-control",
                    "AWS:SourceArn": [
                        "arn:aws:cloudtrail:ap-northeast-1:{アカウントB ID}:trail/demo-trail",
                        "arn:aws:cloudtrail:ap-northeast-1:{アカウントA ID}:trail/demo-trail"
                    ]
                }
            }
        }
    ]
}


		

3. KMSキーポリシーの編集

先ほどアカウントBに作成したKMSキー「demo-cloudtrail-bucket-key」のキーポリシーをアカウントAでも使用できるように編集します。

変更前
			
			{
	"Version": "2012-10-17",
	"Id": "Key policy created by CloudTrail",
	"Statement": [
		{
			"Sid": "Enable IAM User Permissions",
			"Effect": "Allow",
			"Principal": {
				"AWS": [
					"arn:aws:sts::{アカウントB ID}:assumed-role/hogehoge/hogehoge",
					"arn:aws:iam::{アカウントB ID}:root"
				]
			},
			"Action": "kms:*",
			"Resource": "*"
		},
		{
			"Sid": "Allow CloudTrail to encrypt logs",
			"Effect": "Allow",
			"Principal": {
				"Service": "cloudtrail.amazonaws.com"
			},
			"Action": "kms:GenerateDataKey*",
			"Resource": "*",
			"Condition": {
				"StringEquals": {
					"aws:SourceArn": "arn:aws:cloudtrail:ap-northeast-1:{アカウントB ID}:trail/demo-trail"
				},
				"StringLike": {
					"kms:EncryptionContext:aws:cloudtrail:arn": "arn:aws:cloudtrail:*:{アカウントB ID}:trail/*"
				}
			}
		},
		{
			"Sid": "Allow CloudTrail to describe key",
			"Effect": "Allow",
			"Principal": {
				"Service": "cloudtrail.amazonaws.com"
			},
			"Action": "kms:DescribeKey",
			"Resource": "*"
		},
		{
			"Sid": "Allow principals in the account to decrypt log files",
			"Effect": "Allow",
			"Principal": {
				"AWS": "*"
			},
			"Action": [
				"kms:Decrypt",
				"kms:ReEncryptFrom"
			],
			"Resource": "*",
			"Condition": {
				"StringEquals": {
					"kms:CallerAccount": "{アカウントB ID}"
				},
				"StringLike": {
					"kms:EncryptionContext:aws:cloudtrail:arn": "arn:aws:cloudtrail:*:{アカウントB ID}:trail/*"
				}
			}
		},
		{
			"Sid": "Enable cross account log decryption",
			"Effect": "Allow",
			"Principal": {
				"AWS": "*"
			},
			"Action": [
				"kms:Decrypt",
				"kms:ReEncryptFrom"
			],
			"Resource": "*",
			"Condition": {
				"StringEquals": {
					"kms:CallerAccount": "{アカウントB ID}"
				},
				"StringLike": {
					"kms:EncryptionContext:aws:cloudtrail:arn": "arn:aws:cloudtrail:*:{アカウントB ID}:trail/*"
				}
			}
		}
	]
}

		

変更箇所は「kms:GenerateDataKey*」のCondition部分を使用するアカウント分増やしてあげれば良いです。そのほかの編集は不要です。
こちらもバケットポリシー同様アカウントが増えればその分編集する必要があります。

変更後
			
			{
	"Sid": "Allow CloudTrail to encrypt logs",
	"Effect": "Allow",
	"Principal": {
		"Service": "cloudtrail.amazonaws.com"
	},
	"Action": "kms:GenerateDataKey*",
	"Resource": "*",
	"Condition": {
		"StringEquals": {
			"aws:SourceArn": [
				"arn:aws:cloudtrail:ap-northeast-1:{アカウントB ID}:trail/demo-trail",
				"arn:aws:cloudtrail:ap-northeast-1:{アカウントA ID}:trail/demo-trail"
			]
		},
		"StringLike": {
			"kms:EncryptionContext:aws:cloudtrail:arn": [
				"arn:aws:cloudtrail:*:{アカウントB ID}:trail/*",
				"arn:aws:cloudtrail:*:{アカウントA ID}:trail/*"
			]
		}
	}
}

		

4. アカウントAでCloudTrail証跡を作成する。

ここまでで、アカウントAからアカウントBのS3バケットとKMSキーを参照する準備ができたので、アカウントAのCloudTrail証跡を作成してみます。

設定のポイントとしてS3バケット部分はアカウントBで作成した「バケット名」を設定し、KMSキーの部分はアカウントBで作成したカスタマー管理キーの「ARN」を設定してあげます。

2025-09-12-cloudtrail-crossaccount-s3-07

その他、先ほどと同様に保管するイベント等の設定を行います。

2025-09-12-cloudtrail-crossaccount-s3-08

「確認と作成」項目にて証跡ログの場所がきちんと別アカウントのS3バケットになっていればOKです。

2025-09-12-cloudtrail-crossaccount-s3-09

こちらのアカウントでも以下の様に証跡が無事作成されると成功です。

2025-09-12-cloudtrail-crossaccount-s3-10

5. アカウントBのバケットにてイベント履歴が集約されているか確認

証跡作成後、10分程度待つと以下のようにアカウントAとB両方のイベント履歴がアカウントB内のS3バケットにきちんと保存できていることが確認できました。

2025-09-12-cloudtrail-crossaccount-s3-11

2025-09-12-cloudtrail-crossaccount-s3-12

最後に

今回はCloudTrailのイベント履歴をシンプルにクロスアカウントで単一のS3バケットへ集約する設定をやってみました。アカウント量が増えてくると、設定変更の自動化やOrganizationsの検討も視野に入れましょう。
このブログが誰かの参考になれば幸いです。今回は以上です。

この記事をシェアする

FacebookHatena blogX

関連記事