以下の内容はhttps://techblog.forgevision.com/entry/aws/cloudfront/wafより取得しました。


CloudFrontのWAF付け替えで生成AIに振り回された話

こんにちは、AWSグループのナガトモです🙋‍♀️(アミーゴでも可)

今月、7/7にJAWSミートというイベントに参加させていただきました。
肉(ミート)と会う(ミート)をかけたどちらも大変魅力的なイベントでした。

エンジニア・ミーツ・ミート!ということで、発表した内容です。

WAF ルールにまつわる生成 AI 奮闘記

先日 AWS re:Inforce 2025 で発表された AWS WAF の新しいコンソール体験、みなさんもう触りましたか?

わたしはと言うと、

「WAF の UI が変わったらしい」→「へぇ〜便利そう」→「…ほんまに?」

みたいなテンションで触り始めて、最終的に 別のところ(CloudFront)で盛大にハマるという、いつもの流れをやりました。

というわけでこの記事では、

WAF ルール運用(というか CloudFront 連携)で生成 AI に振り回された話
結局どうやるのが正解なのか(結論:UpdateDistribution)

という流れで、お届けします。
同じところで「???」ってなってる方の助けになればうれしいです!

AWS WAFのアップデートよりも言いたいことがある!

まず:re:Inforce 2025 で AWS WAF の何が変わったの?
というところに関しては、re:Inforce で大きくアップデートされたAWS WAFの話は、上司がブログにまとめていますので、こちらをお読みください。

techblog.forgevision.com

わたしがしたかったのは超シンプルで、

  • 営業時間が終わったら Web サイトをメンテナンスページにする
  • 営業時間開始前にメンテナンスを解除する

でした。

「よし、じゃぁEventBridgeでスケジュール組んでLambda呼び出して、CloudFrontに関連付けてるWAFを切り替えよ!」

…ってことで、まずはChatGPT先生に聞いてみました。

ChatGPT が提案してきた(それっぽい)方法

多くのAWSサービスって、WAFを付けるとき AssociateWebACL(API的には wafv2:AssociateWebACL )でいけるじゃないですか。
なのでChatGPTも当然のようにそれを出してきました。

「おお、いい感じやん!さすがやん!」

と思って実行したら……

生成AIあるある - 聞くたびに言うことが変わる

で、もう一回聞くじゃないですか。
そしたら、「真実はいつもひとつ」みたいなテンションで手のひら返してきます。。

ChatGPT「条件を満たせば使えるよ」

『いや先生、わたしが悪いん?』ってなりますよね。

結論:CloudFront は AssociateWebACL じゃない。UpdateDistribution だ。

ここが超重要ポイントです。

AWSの公式APIリファレンスに はっきり 書いてあります。

AssociateWebACL は CloudFront 以外に使う。CloudFront の場合は UpdateDistribution を呼ぶ。

docs.aws.amazon.com

つまり、

CloudFront はグローバルサービスなので、WAFの付け外しが「他リソースの関連付け」ではなくて、CloudFrontディストリビューション設定の一部として扱われるってことですね。

実装メモ:LambdaでCloudFrontのWebACLを付け替える

じゃあ UpdateDistribution ってどうやるの?が以下です。
わたし的ポイントは GetDistributionConfigETagを取ってきて、設定を丸ごと更新するところです。

import os
import boto3

cloudfront = boto3.client("cloudfront")

DISTRIBUTION_ID = os.environ["DISTRIBUTION_ID"]
# CloudFront に付ける WAFv2 Web ACL の ARN(スコープ CLOUDFRONT のやつ)
WEB_ACL_ARN = os.environ.get("WEB_ACL_ARN", "")  # 外す場合は空文字にする運用でもOK

def handler(event, context):
    # 1) 現在の設定と ETag を取得
    res = cloudfront.get_distribution_config(Id=DISTRIBUTION_ID)
    etag = res["ETag"]
    config = res["DistributionConfig"]

    # 2) WebACLId を差し替え(CloudFront 側の項目名は WebACLId)
    config["WebACLId"] = WEB_ACL_ARN  # 外すときは ""(もしくは未設定相当)に

    # 3) 更新(IfMatch に ETag 必須)
    cloudfront.update_distribution(
        Id=DISTRIBUTION_ID,
        IfMatch=etag,
        DistributionConfig=config,
    )

    return {"status": "ok", "web_acl": WEB_ACL_ARN}

補足

  • CloudFrontは、他のサービスと違い「WAF を付けるAPIが違う」と覚えるのがオススメ
  • Terraformでも同じで、CloudFront は web_acl_iddistribution 側に入れます

まとめ:教訓

最後にまとめます。

AWS WAFはリニューアルしたけど、CloudFront 周りは相変わらずクセがあリマス。
特に、表示や関連付けで混乱しやすいと感じます。

CloudFrontにWAFを付けたり外したりするのは、AssociateWebACL ではなく UpdateDistribution とご記憶ください!

あと、生成 AI は便利だけど、AIの言うことを鵜呑みにしない。 エンジニアは失敗から学ぶ生き物。 日々成長しているわたしに乾杯🍻(ってことで終わります)

それではまた🙋‍♀️




以上の内容はhttps://techblog.forgevision.com/entry/aws/cloudfront/wafより取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14