😑

boto3でAWS WAFのIPリストが取得できない件

2024/07/17に公開

はじめに

ちょっとしたトラブルシューティングの記事になります。

使ったもの

使ったもの バージョン
macOS Sonoma 14.2
Python 3.9系
boto3 1.34.110

何があったのか?

CloudFrontに設定してあるWAFv2から、指定したIPリストを取得するという非常にシンプルな処理を実装しようとしていました。で、boto3 WAFv2のドキュメントを読んでみて、「ああ、このget_ip_set()って関数使えばいいんだ〜」と思い早速実装してみました。
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/wafv2/client/get_ip_set.html

main.py
def get_ip_set_list() -> List:
    client = boto3.client('wafv2')
    IP_SET_NAME = 'IP_SET_NAME'
    Scope = 'CLOUDFRONT'
    Id = 'IP_SET_ID'

    response = client.get_ip_set(
        Name=IP_SET_NAME,
        Scope=Scope,
        Id=Id
    )

    return response['IPSet']['Addresses']

def main():
    ip_set = get_ip_set_list()
    print(ip_set)

if __name__ == '__main__':
    main()

が、実行すると何故かエラーが発生。

error
botocore.errorfactory.WAFInvalidParameterException: An error occurred (WAFInvalidParameterException) when calling the GetIPSet operation: Error reason: The scope is not valid., field: SCOPE_VALUE, parameter: CLOUDFRONT

SCOPEのCLOUDFRONTがどうやら無効とのことです。
ドキュメントには下記のように、スコープには「CLOUDFRONT」と「REGIONAL」が指定できるように見受けられますし、それ以外のパラメータはどこにも書いてありません...🧐

response = client.get_ip_set(
    Name='string',
    Scope='CLOUDFRONT'|'REGIONAL',
    Id='string'
)

解決方法

get_ip_set()関数の引数の欄をもう少し注意深く見てみると、下記記述がありました。

To work with CloudFront, you must also specify the Region US East (N. Virginia) as follows:
CLI - Specify the Region when you use the CloudFront scope: --scope=CLOUDFRONT --region=us-east-1.
API and SDKs - For all calls, use the Region endpoint us-east-1.
(日本語訳)
CloudFrontを使用するには、以下のようにRegion US East (N. Virginia)も指定する必要があります:
CLI - CloudFrontスコープを使用する際にRegionを指定します: --scope=CLOUDFRONT --region=us-east-1.
APIとSDK - すべてのコールで、Regionエンドポイントus-east-1を使用します。

SCOPEでCLOUDFRONTを指定するには、regionにus-east-1を指定しろと懇切丁寧に書いてあるじゃないですか!そもそもWAFv2のドキュメントのトップページにも書いてあります。
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/wafv2.html

For Amazon CloudFront applications, you must use the API endpoint listed for US East (N. Virginia): us-east-1.
(日本語訳)
Amazon CloudFrontアプリケーションでは、US East (N. Virginia)のAPIエンドポイントus-east-1を使用する必要があります。

オイオイオイ、ここまでくると私の目が節穴すぎて恥ずかしい。
で、結局以下のコードで実装したところ、なんとか実行することができました。

main.py
adef get_ip_set_list() -> List:
    ### us-east-1追加 ###
    client = boto3.client('wafv2', region_name='us-east-1')
    ####################
    IP_SET_NAME = 'IP_SET_NAME'
    Scope = 'CLOUDFRONT'
    Id = 'IP_SET_ID'

    response = client.get_ip_set(
        Name=IP_SET_NAME,
        Scope=Scope,
        Id=Id
    )

    return response['IPSet']['Addresses']

def main():
    ip_set = get_ip_set_list()
    print(ip_set)

if __name__ == '__main__':
    main()

result
['1.1.1.1/32', '2.2.2.2/32' .....<長いので割愛>

おわりに

ドキュメントは丁寧に読みましょうね...。

参考資料

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/wafv2.html
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/wafv2/client/get_ip_set.html

GitHubで編集を提案

Discussion