Public IPv4 アドレスが関連づいているリソースをスクリプトで一括特定する(マルチアカウントかつマルチリージョン)

記事タイトルとURLをコピーする

こんにちは!
エンタープライズクラウド部技術2課の日高です。

2023年7月末に発表された AWS における Public IPv4 アドレスの有料化に伴い、事前に影響を確認する方が多いと思います。
その調査方法の1つとして、Public IPv4 アドレスが関連づいているリソースを一括特定するスクリプトを作成しました。

※ENIの情報を元に取得するので、ENIに紐づいていないPublic IPv4 の情報は取得できないのでご注意ください。

はじめに

Public IPv4 アドレスの有料化が及ぼす利用料金への影響を確認する方法については、以下の弊社ブログ記事をご覧ください

blog.serverworks.co.jp

上記のブログに書かれている通り、費用発生の原因となるリソースを特定する方法としてAmazon VPC IP Address Manager Public IP Insights (IPAM)があります。
しかし、現状ではマルチアカウントやマルチリージョンで一括で費用発生の原因となるリソースを特定することはできません。

そのためマルチアカウントかつマルチリージョンで使用されているPublic IPv4 アドレスを特定するスクリプトを作成しました。
※スクリプトを利用するだけの場合は「 前提と作成したスクリプト」を、スクリプトの詳細を知りたい方は「スクリプトの詳細」をご覧ください。

前提と作成したスクリプト

前提

  • AWS CLIがインストールされている
  • スイッチロールできる設定が済まされている(AWS CLI の設定 (~/.aws/config ファイル) にて、ロールの情報が設定されている)
  • 実行環境のOSがUnix系

作成したスクリプト

スイッチロール先のプロファイルで指定されたアカウントのENIの情報を取得しに行きます。
Public IPv4 アドレスが紐づいているENIのVPC IDやInterfaceTypeを取得し、CSVファイルに出力されます。(これにより費用発生の原因となるリソースを特定できます。)

#!/bin/bash -eu

# AWS CLIのプロファイル名のリスト。これらのプロファイルは~/.aws/configおよび~/.aws/credentialsに定義されている必要があります。
profiles=(profile1 profile2 ...) # 実際のプロファイル名に置き換えてください。

# 出力するCSVファイルのヘッダー
echo "OwnerId,NetworkInterfaceId,PublicIp,VPCId,SubnetId,InterfaceType,Region" > eni_details.csv

# 初回のプロファイルからリージョンを取得
regions=$(aws ec2 describe-regions --profile "${profiles[0]}" --query "Regions[].RegionName" --output text)

# プロファイルごとの処理
for profile in "${profiles[@]}"; do

    # リージョンごとの処理
    for region in $regions; do
        # ENIの詳細情報を取得
        aws ec2 describe-network-interfaces --region $region --profile $profile | jq -r \
        --arg region "$region" \
        '.NetworkInterfaces[] | 
        select(.Association != null) |
        [
            .OwnerId, 
            .NetworkInterfaceId, 
            .Association.PublicIp, 
            .VpcId, 
            .SubnetId,
            .InterfaceType,
            $region
        ] | 
        @csv' >> eni_details.csv
    done
done

利用方法

準備

  • 上記のスクリプトを実行するフォルダ配下に作成する。
  • この際、実際のプロファイル名にprofilesのリストを置き換えてください。

実行コマンド

  • 下記コマンドを実行します。
  • bash <保存時のスクリプト名>
    • 私の場合は「publicipv4_Assessment.sh」で保存しているのでbash publicipv4_Assessment.shが実行コマンドになります。

スクリプトの実行結果

下記画像のようにCSVファイルに「AWSアカウントID、ENI ID、PublicIP、VPCID、SubnetID、InterfaceType、Region」が出力されます。

スクリプトの詳細

スクリプトの解説をします。

#!/bin/bash -eu

# AWS CLIのプロファイル名のリスト。これらのプロファイルは~/.aws/configおよび~/.aws/credentialsに定義されている必要があります。
profiles=(profile1 profile2 ...) # 実際のプロファイル名に置き換えてください。

# 出力するCSVファイルのヘッダー
echo "OwnerId,NetworkInterfaceId,PublicIp,VPCId,SubnetId,InterfaceType,Region" > eni_details.csv

# 初回のプロファイルからリージョンを取得
regions=$(aws ec2 describe-regions --profile "${profiles[0]}" --query "Regions[].RegionName" --output text)

# プロファイルごとの処理
for profile in "${profiles[@]}"; do

    # リージョンごとの処理
    for region in $regions; do
        # ENIの詳細情報を取得
        aws ec2 describe-network-interfaces --region $region --profile $profile | jq -r \
        --arg region "$region" \
        '.NetworkInterfaces[] | 
        select(.Association != null) |
        [
            .OwnerId, 
            .NetworkInterfaceId, 
            .Association.PublicIp, 
            .VpcId, 
            .SubnetId,
            .InterfaceType,
            $region
        ] | 
        @csv' >> eni_details.csv
    done
done
#!/bin/bash -eu:
  • これはshebang行と呼ばれ、スクリプトの実行に使用するシェルを指定しています。
  • -euオプションは、エラーが発生した場合や未定義の変数を参照した場合にスクリプトの実行を中止するためのものです。
profiles=(profile1 profile2 ...):
  • profilesという配列を定義しています。
  • <profile1やprofile2は、~/.aws/configや~/.aws/credentialsに定義されているAWS CLIのプロファイル名を指しています。
echo "OwnerId,...,Region" > eni_details.csv:
  • 新しいCSVファイルeni_details.csvを作成し、ヘッダーラインを書き込んでいます。
regions=$(aws ec2 describe-regions ...):
  • AWS CLIを使用して、最初のプロファイルで利用可能なリージョンの一覧を取得しています。
  • --queryオプションは、取得したデータから特定の情報だけを抽出するためのものです。
for profile in "${profiles[@]}"; do:
  • 定義したプロファイルのリストを順に処理しています。
for region in $regions; do:
  • 各プロファイルで利用可能なリージョンを順に処理しています。
aws ec2 describe-network-interfaces ... | jq -r ...:
  • describe-network-interfacesコマンドでENIの詳細情報を取得しています。
  • jqはJSONのパースツールで、必要なデータを抽出したり、整形したりするために使われます。ここではENIの特定の属性をCSV形式で出力しています。

※「aws ec2 describe-network-interfaces」について詳しくは以下をご覧ください。

docs.aws.amazon.com

>> eni_details.csv:
  • 7行目で整形されたデータをeni_details.csvファイルに追記しています。
done:
  • forループを閉じるためのものです。

まとめ

Public IPv4 アドレスにかかる料金は1時間当たり0.005USDですが、多くのPublic IPv4 アドレスを利用している場合無視できない金額が課金されます。
そのため一度は利用料への影響度合いをご確認されることを推奨します。

本記事が誰かの助けになれば幸いです。

日高 僚太(執筆記事の一覧)

EC部ソリューションアーキテクト2課 / AWS認定資格 12冠

2022年IT未経験で新卒入社しました。
最近はダーツとサウナが気になっています!
記事に関するお問い合わせや修正依頼⇒ hidaka@serverworks.co.jp