こんにちは。AWS CLIが好きな福島です。
はじめに
今回は、VPCピアリングからTGWに移行する際の事前調査として、 VPCフローログからVPCピアリングのトラフィック量を調査したため、その方法をブログに記載いたします。
前提
ログ形式
今回、ブログに記載するクエリを使う場合の前提として、 VPCフローログのログ形式をカスタムし、flow-directionおよびtraffic-pathが末尾に出力されるように設定しておきます。
- デフォルト
VPCフローログのログ形式のデフォルトは以下の通りです。
${version} ${account-id} ${interface-id} ${srcaddr} ${dstaddr} ${srcport} ${dstport} ${protocol} ${packets} ${bytes} ${start} ${end} ${action} ${log-status}
- カスタム
VPCフローログのログ形式を以下の通り、カスタムします。 デフォルト形式に以下4つの列を追加します。
${pkt-src-aws-service} ${pkt-dst-aws-service} ${flow-direction} ${traffic-path} ※${pkt-src-aws-service} ${pkt-dst-aws-service}は今回の分析に必須ではないです。
カスタムしたのログ形式は以下の通りです。
${version} ${account-id} ${interface-id} ${srcaddr} ${dstaddr} ${srcport} ${dstport} ${protocol} ${packets} ${bytes} ${start} ${end} ${action} ${log-status} ${pkt-src-aws-service} ${pkt-dst-aws-service} ${flow-direction} ${traffic-path}
traffic-path
traffic-pathには、トラフィックの送信先に応じて数字が記載されます。詳細は以下の通りです。
出力トラフィックが送信先につながるパス。 トラフィックが出力トラフィックであるかどうかを判断するには、flow-direction フィールドを確認します。 指定できる値は次のとおりです。いずれの値も適用されない場合、フィールドは - に設定されます。
1 — 同じ VPC 内の別のリソース経由 2 — インターネットゲートウェイまたはゲートウェイ VPC エンドポイント経由 3 — 仮想プライベートゲートウェイ経由 4 — リージョン内 VPC ピア接続経由 5 — リージョン間 VPC ピア接続経由 6 — ローカルゲートウェイ経由 7 — ゲートウェイ VPC エンドポイント経由 (Nitro ベースのインスタンスのみ) 8 — インターネットゲートウェイ経由 (Nitro ベースのインスタンスのみ)
補足
ログ形式のカスタムをマネジメントコンソール上から実行する場合、 少し手間なので以下の変数を定義後、コマンドを実行すると楽です。
VPC_ID="VPCのIDを指定" CW_LOGS_NAME="CloudWatch Logsのロググループ名を指定" FLOWLOGS_IAM_ARN="VPCフローログを出力する際のIAMロールのARNを指定"
aws ec2 create-flow-logs \ --resource-ids ${VPC_ID} \ --resource-type VPC \ --traffic-type ALL \ --deliver-logs-permission-arn ${FLOWLOGS_IAM_ARN} \ --log-group-name ${CW_LOGS_NAME} \ --max-aggregation-interval 60 \ --log-format '${version} ${account-id} ${interface-id} ${srcaddr} ${dstaddr} ${srcport} ${dstport} ${protocol} ${packets} ${bytes} ${start} ${end} ${action} ${log-status} ${pkt-src-aws-service} ${pkt-dst-aws-service} ${flow-direction} ${traffic-path}'
クエリ一覧
⓪クエリ実行前の準備
クエリを実行する前に対象となるロググループおよび調査するログの範囲(時間)を指定します。 ※今回は、fk-test-vpcとfk-test2-vpc間でのVPCピアリングしています。
①リージョン内のVPCピアリングのトラフィック量の出力
- クエリ
filter @message =~ /egress 4$/ | stats sum(bytes) as TotalBytes | display TotalBytes
- 実行結果
- 解説
以下のように出力されるログに対して、messageの末尾が「egress 4」(赤枠)のbytesの値(青枠)をsum関数で集計します。 egress だけに出力を絞っているのは、両方のVPCフローログをクエリの対象としているためです。 (そもそも、ingress 4という値は出力されなそうでしたが...)
②リージョン内のVPCピアリングのトラフィック量をENI単位で出力
- クエリ
filter @message =~ /egress 4$/ | stats sum(bytes) as TotalBytes by interfaceId | sort TotalBytes DESC
- 実行結果
- 解説
1個前のクエリとほぼ同様で、by interfaceIdという部分が異なります。 これは、interfaceid(ENI)ごと(緑枠)に集計結果を出力する意味となります。
③時間単位でリージョン内のVPCピアリングのトラフィック量を出力
これは、ログの範囲を変えつつ、①のクエリを実行するだけでいいのですが、 マネジメントコンソールからその作業は実行するのは、少し苦労します。
そのため、私は以下のスクリプトを使いました。
- vpc_flowlogs_check.sh
#!/bin/bash ## 第1引数(ログの範囲)を代入 YYYY_MM_DD=${1} ## 第1引数をUNIXTIMEに変換 start_time=$(date -d "${YYYY_MM_DD}" +%s) ## クエリの終了時間を設定(1時間間隔でクエリを実行するため、3599(秒)加算) end_time=$(expr ${start_time} + 3599) ## 第2引数(ロググループ)を代入 log_group_names=${2} echo "start_time,end_time,traffic_bytes,statistics_bytes,query_id" ## 1日を1時間単位で集計するため、24回処理を実行 for i in {0..23} do ## クエリを実行し、返り値をquery_idに代入 query_id=$(aws logs start-query \ --log-group-names ${log_group_names}\ --start-time "${start_time}000" \ --end-time "${end_time}000" \ --query-string 'filter @message =~ /egress 4$/ | stats sum(bytes) as TotalBytes | display TotalBytes' \ --query "queryId" --output text) ## クエリが完了するのを待つ(最大50秒) for i in {0..9} do ## クエリのステータスを確認 query_status=$(aws logs get-query-results \ --query-id ${query_id} \ --query "status" --output text) ## クエリのステータスが「Complete」になった場合処理を抜ける if [[ "Complete" == ${query_status} ]] ; then query_result=$(aws logs get-query-results \ --query-id ${query_id} \ --query "[results[0][0].value,statistics.bytesScanned]" --output text \ | tr "\t" ",") break fi sleep 5 done ## クエリの結果を標準出力 echo "$(date --date @${start_time} +'%Y/%m/%d %H:%M:%S'),$(date --date @${end_time} +'%Y/%m/%d %H:%M:%S'),${query_result},${query_id}" start_time=$(expr ${end_time} + 1) end_time=$(expr ${start_time} + 3599) i+=1 unset total_bytes done
- 使い方
# ./vpc_flowlogs_check.sh [調査したい日付] [ロググループ名("で囲み、スペース区切りで複数指定)]
- 実行例
# ./vpc_flowlogs_check.sh 2022-03-28 "fk-test-vpc fk-test2-vpc" start_time,end_time,traffic_bytes,statistics_bytes,query_id 2022/03/28 00:00:00,2022/03/28 00:59:59,None,16407.0,79b6b8d1-d05d-4505-bd56-cb062a2e4a13 2022/03/28 01:00:00,2022/03/28 01:59:59,None,16407.0,03ab240c-a47f-42c3-bfd1-c3faaf7e482e 2022/03/28 02:00:00,2022/03/28 02:59:59,None,16407.0,aaceea5f-30e5-4c84-b745-b9a132b91cf2 2022/03/28 03:00:00,2022/03/28 03:59:59,None,16407.0,6d7cb1ef-d3c7-4329-8001-f4bd3ed01f27 2022/03/28 04:00:00,2022/03/28 04:59:59,None,16407.0,4df1c986-c985-45d7-950a-5f7e802b1a58 2022/03/28 05:00:00,2022/03/28 05:59:59,None,16407.0,0fe2f628-09bd-45b6-b329-1f88c69006a0 2022/03/28 06:00:00,2022/03/28 06:59:59,None,16407.0,ffaef180-a9ee-4ed7-a231-338e75d40e61 2022/03/28 07:00:00,2022/03/28 07:59:59,None,16407.0,69b9068d-582d-47e0-9b1a-9a7d3a95a399 2022/03/28 08:00:00,2022/03/28 08:59:59,None,16407.0,c500035e-dfa1-46c2-a2f5-1f1cb1ee560e 2022/03/28 09:00:00,2022/03/28 09:59:59,None,16407.0,61395b09-019d-4d23-b576-4357167dbd3b 2022/03/28 10:00:00,2022/03/28 10:59:59,None,16407.0,6ad4c3c5-356a-4a6d-9c0e-8f2c115adbc8 2022/03/28 11:00:00,2022/03/28 11:59:59,None,16407.0,b8c2ab36-240a-412e-bd5c-0268d2fc403f 2022/03/28 12:00:00,2022/03/28 12:59:59,None,16407.0,ae67c89a-3d12-4ae9-ba57-2c2a9760c899 2022/03/28 13:00:00,2022/03/28 13:59:59,None,16407.0,76a61753-6f2f-43b9-a170-1e6bd7e67d86 2022/03/28 14:00:00,2022/03/28 14:59:59,None,16407.0,755ae266-c60e-4161-8df7-124fb8cabc00 2022/03/28 15:00:00,2022/03/28 15:59:59,None,16407.0,64301660-c842-4f6a-9579-bfbb3b4f988d 2022/03/28 16:00:00,2022/03/28 16:59:59,1092,309332.0,3da35432-d6dc-4c63-b3cb-d224cbd0f5ca 2022/03/28 17:00:00,2022/03/28 17:59:59,336,932346.0,2bfdcdbb-db89-452d-80cb-1044a1dbba5d 2022/03/28 18:00:00,2022/03/28 18:59:59,None,889753.0,4140acdb-3665-4349-ae67-3d10e3c8e17b 2022/03/28 19:00:00,2022/03/28 19:59:59,None,929301.0,4581454b-7cc1-4c69-a998-bfb7734d4fc8 2022/03/28 20:00:00,2022/03/28 20:59:59,None,905492.0,6a9fb063-9fe3-4fda-9f18-09d36322841b 2022/03/28 21:00:00,2022/03/28 21:59:59,None,916564.0,a2e7b3fc-bc53-4879-9890-6d438260fe95 2022/03/28 22:00:00,2022/03/28 22:59:59,None,917511.0,7a9a40f2-8deb-480c-9447-ff53a66c0527 2022/03/28 23:00:00,2022/03/28 23:59:59,None,934279.0,ae91dd6f-2a22-422f-82fe-45a5e2785561
各項目の意味は以下の通りです。statistics_bytesを出力しているのは、この値に応じてCloudWatch Logs Insightsの料金が代わるため、一応出力しています。
start_time: 開始時刻 end_time: 終了時刻 traffic_bytes: トラフィック量 statistics_bytes: 分析したログの総量 query_id: クエリID
- 補足 クエリIDを指定することで実際の分析結果を確認することができます。
# aws logs get-query-results --query-id 2bfdcdbb-db89-452d-80cb-1044a1dbba5d { "results": [ [ { "field": "TotalBytes", "value": "336" } ] ], "statistics": { "recordsMatched": 2.0, "recordsScanned": 6470.0, "bytesScanned": 932346.0 }, "status": "Complete" } #
終わりに
今回は、VPCピアリングのトラフィックをVPCフローログから調査してみました。 どなたかのお役に立てれば幸いです。