こんにちは、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の話は、上司がブログにまとめていますので、こちらをお読みください。
わたしがしたかったのは超シンプルで、
- 営業時間が終わったら 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 を呼ぶ。
つまり、
CloudFront はグローバルサービスなので、WAFの付け外しが「他リソースの関連付け」ではなくて、CloudFrontディストリビューション設定の一部として扱われるってことですね。
実装メモ:LambdaでCloudFrontのWebACLを付け替える
じゃあ UpdateDistribution ってどうやるの?が以下です。
わたし的ポイントは GetDistributionConfigでETagを取ってきて、設定を丸ごと更新するところです。
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_idをdistribution側に入れます
まとめ:教訓
最後にまとめます。
AWS WAFはリニューアルしたけど、CloudFront 周りは相変わらずクセがあリマス。
特に、表示や関連付けで混乱しやすいと感じます。
CloudFrontにWAFを付けたり外したりするのは、AssociateWebACL ではなく UpdateDistribution とご記憶ください!
あと、生成 AI は便利だけど、AIの言うことを鵜呑みにしない。 エンジニアは失敗から学ぶ生き物。 日々成長しているわたしに乾杯🍻(ってことで終わります)
それではまた🙋♀️