Techfirm Cloud Architect Blog

テックファーム株式会社クラウドインフラグループのブログ

Amazon Athenaでフローログを分析する

はじめに

AWSのVPCフローログ(以下、フローログ)は、VPC内のネットワークトラフィックを詳細に記録する機能です。
このログデータには、送信元・送信先のIPアドレス、ポート番号、プロトコル、データ転送量など、ネットワークの動きを理解する上で重要な情報が含まれています。
しかし、フローログのデータ量は膨大になりがちで、効率的な分析が課題となっています。
Amazon Athena(以下、Athena)を使用すると、クエリを使ってフローログを柔軟に分析できます。

本記事では、Athenaでフローログを分析するための具体的な手順を解説します。

前提条件

本記事は、以下の前提で手順を解説します。

  • フローログは設定済みで、S3上にログが出力されているものとする
  • Athenaのクエリ結果出力先は設定済みで、クエリが実行できる状態とする

手順

フローログバージョンの確認

フローログには複数のバージョンが存在し、バージョンによってログの形式が異なります。Athenaでの分析を始める前に、まずご使用のフローログバージョンを確認しましょう。
確認手順:

  • AWSマネジメントコンソールのVPCページを開きます
  • フローログの設定画面に移動します
  • 「ログ行の形式」の欄を確認します
    • 「デフォルト」の場合:フローログバージョン2
    • 「カスタム」の場合:フローログバージョン3~8のいずれか
  • 「デフォルト」、または「カスタム」を押下すると、設定されているフィールドの一覧が表示されます

vpc-01

本記事では、以降の手順はすべてフローログバージョン2を前提に説明します。
バージョン2以外をご利用の場合は、ご自身の環境のフローログバージョンに合わせて、フィールド名などを適宜読み替えてください。

Athenaテーブルの作成

Athenaページを開き、以下クエリを実行して「vpc_flow_logs」テーブルを作成します。
なお本記事では、例としてデフォルトデータベースにテーブルを作成します。必要に応じてデータベースを作成してください。
また、フィールド名、LOCATION句はご自身の環境に合わせて変更してください。

CREATE EXTERNAL TABLE IF NOT EXISTS vpc_flow_logs (
  version int,
  account string,
  interfaceid string,
  sourceaddress string,
  destinationaddress string,
  sourceport int,
  destinationport int,
  protocol int,
  numpackets int,
  numbytes bigint,
  starttime int,
  endtime int,
  action string,
  logstatus string
)
PARTITIONED BY (`date` date)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ' '
LOCATION 's3://<s3 bucket name>/AWSLogs/<aws account id>/vpcflowlogs/<region code>/'
TBLPROPERTIES ("skip.header.line.count"="1");

パーティションの設定

以下クエリを実行してパーティションを作成し、データを読み取れるようにします。 このクエリでは、2025年2月に出力されたフローログが読み取り対象になります。

ALTER TABLE vpc_flow_logs
ADD PARTITION (`date`='2025-02')
LOCATION 's3://<s3 bucket name>/AWSLogs/<aws account id>/vpcflowlogs/<region code>/2025/02/';

Athenaテーブルの作成のクエリには、PARTITIONED句(パーティション分割)が設定されています。このため、パーティションを作成しないとデータを読み取ることができません。
パーティションを使わずにデータを読み取る方法として、テーブル作成時のPARTITIONED句を削除する方法があります。ただし、この方法には注意点があります:

  • 指定したS3パス配下のすべてのログが読み取り対象となるため、Athenaの実行コストが高くなります
  • 大量のデータを処理することになり、クエリの実行時間が長くなります

そのため、PARTITIONED句を削除する場合は、LOCATION句で指定するS3パスを工夫することをオススメします。たとえば、年/月/日のようにパスを具体的に指定することで、読み取り対象となるデータ量を適切に制限できます。

パーティション射影

上記で「ADD PARTITION (date='2025-02')」と指定してパーティションを設定しましたが、複数の月を指定したり、毎月パーティションを追加する作業は非常に手間です。

そこでパーティション射影機能を使うと、パーティションの自動管理が可能になります。
以下がパーティション射影を設定する際の例です。

projection.date.rangeでは「2025/01/01」から現在までの連続した日付のパーティションが自動的に認識されるように設定しています。

CREATE EXTERNAL TABLE IF NOT EXISTS vpc_flow_logs_projection (
  version int,
  account string,
  interfaceid string,
  sourceaddress string,
  destinationaddress string,
  sourceport int,
  destinationport int,
  protocol int,
  numpackets int,
  numbytes bigint,
  starttime int,
  endtime int,
  action string,
  logstatus string
)
PARTITIONED BY (`date` string)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ' '
LOCATION 's3://<s3 bucket name>/AWSLogs/<aws account id>/vpcflowlogs/<region code>/'
TBLPROPERTIES (
  "skip.header.line.count"="1",
  'projection.enabled' = 'true',
  'projection.date.type' = 'date',
  'projection.date.format' = 'yyyy/MM/dd',
  'projection.date.interval' = '1',
  'projection.date.interval.unit' = 'DAYS',
  'projection.date.range' = '2025/01/01,NOW',
  'storage.location.template' = 's3://<s3 bucket name>/AWSLogs/<aws account id>/vpcflowlogs/<region code>/${date}/'
  );

パーティション射影の詳細については、公式ドキュメントをご参照ください。

クエリ例

作成したテーブルに対してクエリを実行し、データを抽出してみます。 次のクエリ例では、100件のフローログを一覧表示します。

SELECT * 
FROM vpc_flow_logs 
LIMIT 100;

次のクエリ例では以下のようなポイントがあります。

  • UNIXTIMEである時刻をJSTに変換
  • numbytesカラムをメガバイトのmegabytesカラムに変換
  • WHERE句で作成したパーティションを指定 ※パーティションを指定した場合に有効
  • WHERE句でJST時刻を指定
SELECT
  from_unixtime(starttime, 9, 0) AS starttime_jst,
  from_unixtime(endtime, 9, 0) AS endtime_jst,
  sourceaddress,
  destinationaddress,
  sourceport,
  destinationport,
  protocol,
  numpackets,
  ROUND(numbytes / 1048576.0, 2) AS megabytes
FROM vpc_flow_logs
WHERE CAST("date" AS VARCHAR) LIKE '2025-02%'
  AND from_unixtime(starttime, 9, 0) >= cast('2025-02-18 12:00:00 +09:00' as timestamp with time zone)
  AND from_unixtime(starttime, 9, 0) <  cast('2025-02-18 13:00:00 +09:00' as timestamp with time zone)
ORDER BY starttime;

おわりに

本記事では、Athenaを使用してフローログを分析する方法について解説してきました。
Athenaを活用することで、従来は手間のかかっていたログ分析作業を、より迅速かつ柔軟に行うことができるようになります。
本記事が、皆様のAWS運用において参考となれば幸いです。