🐡
Amazon Athena パーティショニングプロジェクションと名前付きクエリをやってみた
はじめに
本ページは個人の勉強で使用することを目的に作成しておりますが、記載の誤り等が含まれる場合がございます。
最新の情報についてはAWS公式ドキュメントをご参照ください。
やること
- S3に保存したCloudTrail管理イベントに対してAmazon Athenaでデータのクエリをする。
- イベント名
ConsoleLogin
に一致するイベントを探索する。
- イベント名
-
パーティショニングプロジェクションを行い、クエリの実行時間とスキャンするデータ量を低減する。
- クエリの一部を名前付きクエリとして実行する。
前提条件
1. Athenaワークグループの作成
- Athenaコンソールからワークグループをクリックします。
- ワークグループを作成します。
- ワークグループの詳細
- ワークグループ名:
mori-athena-workgroup
- 説明 - オプション:
My WorkGroup
- ワークグループ名:
- 分析エンジン - 新規
- エンジンのタイプを選択:
Athena SQL
- クエリエンジンをアップグレード:
自動
- エンジンのタイプを選択:
- 認証:
IAM
- クエリ結果の設定 - オプション
- クエリ結果の場所 - オプション:
s3://mori-s3-cloudtrail-management-event/athena-partition/
- 予期されるバケット所有者 - オプション:
未選択
- バケット所有者にクエリ結果に対する完全なコントロールを割り当てる:
選択
- クエリ結果を暗号化:
未選択
- クエリ結果の場所 - オプション:
- 設定
- AWS CloudWatch にクエリメトリクスを発行:
選択
- クライアント側の設定を上書き:
未選択
- Amazon S3 のリクエスタ支払いバケットでクエリをオンにする:
未選択
- AWS CloudWatch にクエリメトリクスを発行:
- クエリごとのデータ使用状況の制御 - オプション
- データ制限:
1TB
- データ制限:
2. データベース・テーブルを定義
- Athenaのクエリエディタで、ワークグループを先程作成した
mori-athena-workgroup
に切り替えます。 - データベースmori_athena_db_consoleloginを作成します。
CREATE DATABASE mori_athena_db_consolelogin
- データベース
mori_athena_db_consolelogin
に切り替えます。
- テーブルを定義します。
CREATE EXTERNAL TABLE mori_athena_table_consolelogin (
eventVersion STRING,
userIdentity STRUCT<
type: STRING,
principalId: STRING,
arn: STRING,
accountId: STRING,
invokedBy: STRING,
accessKeyId: STRING,
userName: STRING,
sessionContext: STRUCT<
attributes: STRUCT<
mfaAuthenticated: STRING,
creationDate: STRING>,
sessionIssuer: STRUCT<
type: STRING,
principalId: STRING,
arn: STRING,
accountId: STRING,
username: STRING>,
ec2RoleDelivery: STRING,
webIdFederationData: MAP<STRING,STRING>>>,
eventTime STRING,
eventSource STRING,
eventName STRING,
awsRegion STRING,
sourceIpAddress STRING,
userAgent STRING,
errorCode STRING,
errorMessage STRING,
requestParameters STRING,
responseElements STRING,
additionalEventData STRING,
requestId STRING,
eventId STRING,
resources ARRAY<STRUCT<
arn: STRING,
accountId: STRING,
type: STRING>>,
eventType STRING,
apiVersion STRING,
readOnly STRING,
recipientAccountId STRING,
serviceEventDetails STRING,
sharedEventID STRING,
vpcEndpointId STRING,
tlsDetails STRUCT<
tlsVersion: STRING,
cipherSuite: STRING,
clientProvidedHostHeader: STRING>
)
COMMENT 'CloudTrail table for mori-s3-cloudtrail-management-event bucket'
PARTITIONED BY (
`region` string,
`timestamp` string
)
ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe'
STORED AS INPUTFORMAT 'com.amazon.emr.cloudtrail.CloudTrailInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION 's3://★CloudTrailイベントを保存しているS3バケット名/AWSLogs/★アカウントID/CloudTrail/'
TBLPROPERTIES (
'classification'='cloudtrail',
'projection.enabled' = 'true',
'projection.timestamp.type' = 'date',
'projection.timestamp.range' = '2024/03/16,NOW',
'projection.timestamp.format' = 'yyyy/MM/dd',
'projection.timestamp.interval' = '1',
'projection.timestamp.interval.unit' = 'DAYS',
'projection.region.type' = 'enum',
'projection.region.values'='ap-south-1,eu-north-1,eu-west-3,eu-west-2,eu-west-1,ap-northeast-3,ap-northeast-2,ap-northeast-1,ca-central-1,sa-east-1,ap-southeast-1,ap-southeast-2,eu-central-1,us-east-1,us-east-2,us-west-1,us-west-2',
'storage.location.template' = 's3://★CloudTrailイベントを保存しているS3バケット名/AWSLogs/★アカウントID/CloudTrail/${region}/${timestamp}'
);
PARTITIONED BYについて
- パーティションキーを定義。
-
region
:CloudTrailログが記録されたリージョンを文字列型で定義 -
timestamp
:CloudTrailログが記録されが年月日を文字列型で定義。
-
TBLPROPERTIESについて
-
'projection.enabled' = 'true',
- プロジェクションをパーティションを有効化。
-
'projection.timestamp.type' = 'date',
- パーティションtimestampを日付型で定義。
-
'projection.timestamp.format' = 'yyyy/MM/dd',
- パーティションtimestampのフォーマットをyyyy/MM/ddで定義。※S3のフォルダ構造に従う。
-
'projection.timestamp.range' = '2024/03/16,NOW',
- クエリ可能なパーティションの幅を限定。
- この場合、S3バケット作成日である2024/03/16から現在までを指定。
-
'projection.timestamp.interval' = '1',
- パーティションを1日単位で区切っているため1を指定。
-
'projection.timestamp.interval.unit' = 'DAYS',
- パーティションが1日単位で区切っているためDAYSを指定。
-
'projection.region.type' = 'enum',
- パーティションregionを列挙型で定義。
-
'projection.region.values'='us-east-1,us-east-2,us-west-1,us-west-2…
- アカウントで有効化されたリージョンを指定
-
mori-query-1
で名前を付けて保存し、実行をクリックします。
※これを 名前付きクエリ(Named Query) と言います。
3. ConsoleLoginイベントを検索
- 新しいクエリを追加して、クエリを作成します。
SELECT *
FROM mori_athena_table_consolelogin
WHERE
eventname = 'ConsoleLogin'
AND
timestamp between '2024/03/18' and '2024/03/30'
;
※作成したテーブルmori_athena_table_consolelogin
をもとに2024/03/18~2024/03/30期間のConsoleLogin
イベントを取得。
-
mori-query-2
で名前を付けて保存し、実行をクリックします。
- スキャンしたデータ:5.40MB
- 手順1のワークグループで指定したS3バケットの
/athena/
配下にmori-query-1
,mori-query-2
,Unsaved
というフォルダが作成されています。
- クエリに名前を付けて保存(名前付きクエリ)した場合、クエリ名がプレフィックスとして追加されます。
- クエリに名前を付けて保存していない場合、単にUnsavedというプレフィックスとなります。
-
mori-query-2/yyyy/mm/dd/
配下に、.csvファイル
と.metadata
ファイルが作成されています。
- csvファイルのに
2024/03/18~2024/03/30
期間のConsoleLogin
イベントが出力されています。
おわりに
- AWSアカウントで有効化されたリージョンは下記AWS CLIコマンドで確認できる。
$ aws ec2 describe-regions \
--filters "Name=opt-in-status,Values=opt*" \
--query "Regions[*].RegionName" | tr -d "\n" | tr -d "[:space:]" | tr -d \"
[ap-south-1,eu-north-1,eu-west-3,eu-west-2,eu-west-1,ap-northeast-3,ap-northeast-2,ap-northeast-1,ca-central-1,sa-east-1,ap-southeast-1,ap-southeast-2,eu-central-1,us-east-1,us-east-2,us-west-1,us-west-2]
- Athenaの実行権限に必要なアクションはクエリを実行するユーザーに対して許可する必要がある。
- CloudTrailイベント保存先S3バケットが東京リージョンにある場合、
yyyy/mm/dd
フォルダは一見JSTに基づいているように見えるが、実際はUTCに基いていることに注意が必要。
※例えば、2024/05/01
フォルダには日本時間で05/01 09:00 ~ 05/02 08:59のイベントが保存されているので、クエリを投げる時には注意が必要である。またAthenaのクエリエディタもUTCに基づいている。
参考
- データベース・テーブル定義
- パーティショニングプロジェクション
- 名前付きクエリ
- Athena料金
Discussion