前提
Athenaのこと、きちんと理解できていないかもしれません。以下の記述はその場しのぎでうまくいっただけの可能性があります。
やりたいこと
CloudTrailのログを必要な項目だけで解析したい。
最初にやってうまくいかなかった方法
ColudTrailのイベント履歴
からAmazon Athena で高度なクエリを実行します
で自動作成されるAthenaのテーブルは、自分で項目を追加することができませんでした。
CREATE EXTERNAL TABLE [TABLE_NAME] (
eventVersion STRING,
userIdentity STRUCT<
type: STRING,
principalId: STRING,
arn: STRING,
accountId: STRING,
invokedBy: STRING,
accessKeyId: STRING,
userName: STRING,
sessionContext: STRUCT<
attributes: STRUCT<
(中略)
sharedEventID STRING,
vpcEndpointId STRING
)
COMMENT 'CloudTrail table for [S3_BUCKET_NAME] bucket'
ROW FORMAT SERDE 'com.amazon.emr.hive.serde.CloudTrailSerde'
STORED AS INPUTFORMAT 'com.amazon.emr.cloudtrail.CloudTrailInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION '[S3_BUCKET_URL]'
TBLPROPERTIES ('classification'='cloudtrail');
ここで指定している項目(例えば userIdentity.type
など)以外は、いくら上記のCREATE TABLE
の内容をコピペしてAthenaで直接必要な項目を追加してテーブルを作成しても、クエリ(SELECT)時にその追加した項目を指定すると構文エラーが起こってしまいました。
どうも ROW FORMAT SERDE 'com.amazon.emr.hive.serde.CloudTrailSerde'
でSerDeをCloudTrailSerdeを指定すると、デフォルトの項目しかシリアライズ・でシリアライズしてくれないもようでした。
うまくいった方法
以下の記事を見つけて解決
CloudTrailログからAmazon Athenaを使ってログイン監査レポートを作成する
こちらの記事では、SerDeをROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
を指定し、CloudTrailのログJSONファイルのから取得していました。
CREATE EXTERNAL TABLE IF NOT EXISTS records_201702 (
records ARRAY<
STRUCT<
eventTime:STRING,
eventSource:STRING,
eventName:STRING,
awsRegion:STRING,
sourceIPAddress:STRING,
userIdentity:STRUCT<
type:STRING,
arn:STRING
>
>
>
)
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
LOCATION 's3://[CloudTrailログ出力バケット名]/[prefix指定があれば]/AWSLogs/[AWSアカウントID]/CloudTrail/[Region]/2017/02';
こうしたらうまくいきました!
ちなみにクエリーは、records[]
に複数含まれるSTRUCT
を取得する必要があるので、以下のようになります。
SELECT \
record.eventTime, \
record.eventName, \
record.userIdentity.type, \
FROM JOIN UNNEST(records) AS t (record) \
WHERE record.eventName = 'GetObject' \
LIMIT 10;
上記はS3のGetObjectイベントだけ10件取得するクエリーです。
最後に
Athenaのことをきちんと理解できていれば、もっとスマートなやり方がある
のかもしれません。もし記述した内容に間違いがあればすぐ訂正いたしますので、ご指摘いただければ嬉しいです。