CloudTrailの委任で、Organizationsの管理アカウント以外で「組織のデータストア」を作成することができます。この時、このデータストアからクエリ実行結果を出力するS3バケットのポリシーでは、 アクセス許可対象の記述にOrganizationsの管理アカウントIDを指定 する必要があります。
クエリ実行画面から 自動生成されるS3バケットはここに作業中のAWSアカウントのIDを入れるためクエリ実行が失敗 します(たぶん「組織のデータストア」作成を委任され実施したAWSアカウントで、そのログの検索など監査をしているでしょうから)。
前提情報
私自身がCloudTrail Lake初利用なので、概要に触れておく。
- CloudTrail LakeはCloudTrail等のセキュリティ系情報特化のデータウェアハウス(以下DWH)。
- データストアとしてS3+SQLエンジン入ってる(多分Athena、つまり裏はPresto系)。
- セキュリティ系だとSecurity Lakeとかなかったっけと思ったけど、あちらはOCSF形式でデータレイク(蓄積)してSIEMソリューションとかにアクセス提供するするものらしい。
DWHなのでSQLでクエリできて、クエリ結果はS3にCSVファイル出力させることもできる。S3は自動生成させてもいいし、適切なバケットポリシーを付与して作成しておいてもいい。
Organizations環境では「組織の証跡」やCloudTrail Lakeの「組織のデータストア」が作成できるけど、CloudTrailの委任管理者のサポートにより、これを別のアカウント(例えばランディングゾーンの考え方で言うログ保管アカウント)で構成、管理することもできるようになった。
問題
じゃあ、まずログ保管アカウントで「組織のデータストア」を作成し、そこでSQLクエリを実行して、S3に結果を出力させたらどうなるか。
- 組織のデータストア … 作れる。
- SQLクエリを実行 … できる。1秒ちょっとで数千件のレコードが返ってきたりする。
- S3出力 … 有効にしてクエリを実行すると、エラーになる。
エラーメッセージは以下の通り。エラーメッセージがリンクになっていて、リンク先も以下の通り。
S3に出力する指定の際、デフォルトではバケットポリシーを付与したS3バケットを作成してくれる。でもその自動作成されたS3バケットでエラーになる。それならばと自分でバケットを作成してバケットポリシーを書いてみたけど、やっぱりエラーになる。エラーメッセージと、S3出力しなければクエリ実行が成功するところからして、問題はやっぱりバケットとバケットポリシーなのだろうけど。
原因
結論を言えば、バケットポリシーで指定するAWSアカウントIDが違っていた。
まずバケットポリシーのサンプルがこんな感じ。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AWSCloudTrailLake1",
"Effect": "Allow",
"Principal": {"Service": "cloudtrail.amazonaws.com"},
"Action": [
"s3:PutObject*",
"s3:Abort*"
],
"Resource": [
"arn:aws:s3:::myBucketName",
"arn:aws:s3:::myBucketName/*"
],
"Condition": {
"StringLike": {
"aws:sourceAccount": "myAccountID",
"aws:sourceArn": "arn:aws:cloudtrail:myQueryRunningRegion:myAccountID:eventdatastore/*"
}
}
},
{
"Sid": "AWSCloudTrailLake2",
"Effect": "Allow",
"Principal": {"Service":"cloudtrail.amazonaws.com"},
"Action": "s3:GetBucketAcl",
"Resource": "arn:aws:s3:::myBucketName",
"Condition": {
"StringLike": {
"aws:sourceAccount": "myAccountID",
"aws:sourceArn": "arn:aws:cloudtrail:myQueryRunningRegion:myAccountID:eventdatastore/*"
}
}
}
]
}
このうち、 myBucketName
を実際のバケット名、 myQueryRunningRegion
をクエリを実行するリージョン( ap-northeast-1
とか)、 myAccountID
をAWSアカウントIDで置き換える。ここで、一つ注記がある。
注記:
これが組織のイベントデータストアである場合は、管理アカウントの AWS アカウント ID を使用する必要があります。
これ、組織のイベントデータストアを委任されたログ保管アカウントで作成している場合は、どうなんでしょうね。Organizationsの管理アカウントのことか、組織のイベントデータストアの管理アカウント(この場合ログ保管アカウント)のことか、どちらでしょう。
正解は、Organizationsの管理アカウントです。
最初は aws:sourceArn
の myAccountID:eventdatastore
という文字列を見て、データストアはここにあるんだから、ここはログ保管アカウントのIDだよなと思った。だとすれば同じConditions内にある aws:sourceAccount
のアカウントIDが違うというのも妙な感じなので、ログ保管アカウントだろうと。で、エラーになる。もう一度考えてみて、今度は自動生成させたバケットポリシーを確認したりして、やっぱり管理アカウントIDの解釈はあってそうだ、他のところに何か問題があるんだろうと考える。なにをやってもエラーになる。
なにをやってもエラーになるので、委任とか考慮できてないのではと思っていた注記に沿って、試しにOrganizationsの管理アカウントのIDを入れてみる。すると、CSV保存できました。
終わりに
僕の解釈が間違ってたわけですが、傷を深くしたのは少なからず 自動生成されるS3バケットとそのバケットポリシーが同じ間違いをしている ことだったと思います。ぜひとも直していただきたいです……ってこれ、サポートチケットきらないといけないやつ、なのかな……?