AWS CDKを利用して、AWS WAFv2をCloudFrontに紐づける方法について紹介します。なお、本記事では、WAFV2をCloudFrontに紐づけるため、WAFV2はus-east-1のStackとする必要があります。また、CloudFrontはap-northeast-1のStackに含めているため、Cross Region参照用に別途Stackを作成しています。
全コードはGithubを参照してください。
Githubはここ
前提条件
- AWS CDK v.2 がインストールされていること
- Python 3.x がインストールされていること
- AWSアカウントがあり、AWS CLIが設定されていること
※Cloud9を使うとこの辺りがPassできるため、Cloud9を使って今回の記事の内容は作成しています。
構築手順
1. CDKアプリの初期化
先ずはCDKアプリの初期化を行います。
$ mkdir cdk-lambda-rds-proxy
$ cd cdk-lambda-rds-proxy
$ cdk init --language python
2.必要なパッケージをインストール
Cross Region参照を使うため、requirements.txtに以下を追加します。
cdk-remote-stack==2.0.10
続いて必要パッケージのインストールになります。
ここでは、CDKアプリを初期化した際に作成された.venvを有効化しています。
$ source .venv/bin/activate
$ pip install -r requirements.txt
3. WAFV2スタックの作成
WAFV2の作成については以下の記事にて紹介済みとなるため、参照してください。
AWS CDK (v2) PythonでWAFv2を使ってベーシック認証を実装する方法
今回はCloudFrontと紐づけるため、WebACLのARNをOutputとして設定する必要があります。そのため、Stackを定義しているClassの末尾に以下の内容を追加しします。
# WebACLのARNをOutputに設定
cdk.CfnOutput(self, 'WebAclArn', value=webacl.attr_arn)
4. CloudFrontスタックの作成
CloudFrontの作成についても既に記事にて紹介しているため、参照して下さい。
AWS CDK Ver.2 PythonでCloudFrontとS3による静的サイトホスティングを作ってみた
今回はWebACLと紐づけるため、DistributionにWebACLの設定を追加します。
distribution = cf.Distribution(
self,
'Distribution',
default_behavior=cf.BehaviorOptions(
origin=cf_origins.S3Origin(bucket)
),
default_root_object='index.html',
# Web ACLの設定を追加
web_acl_id=webacl_arn
)
5. Cross region参照用のスタックを作成
ap-northeast-1のスタックから直接us-east-1のスタックを参照することはできないため、参照するためのスタックを作成します。
ここでは、WAFのスタックでOutputとして設定した値を受取っています。
from constructs import Construct
from cdk_remote_stack import RemoteOutputs
from aws_cdk import (
Stack,
)
class CrossRegionReferenceStack(Stack):
def __init__(
self, scope: Construct, id: str, wafv2_stack, **kwargs
) -> None:
super().__init__(scope, id, **kwargs)
# 依存関係を定義
self.add_dependency(wafv2_stack)
# CloudFormation outputを取得
cfn_outputs = RemoteOutputs(self, 'CfnOutputs', stack=wafv2_stack)
# Web ACL ARN を取得
self.webacl_arn = cfn_outputs.get('WebAclArn')
6. app.pyの記述
それぞれのスタックをapp.pyに記述します。
import aws_cdk as cdk
from cdk_waf_cloudfront.cloudfront import CloudFrontStack
from cdk_waf_cloudfront.cross_region_reference import CrossRegionReferenceStack
from cdk_waf_cloudfront.wafv2 import Wafv2Stack
app = cdk.App()
# ScopeをCloudFrontとするため、us-east-1にStackを作成する
wafv2_stack = Wafv2Stack(
app, 'Wafv2Stack', env=cdk.Environment(region='us-east-1')
)
# us-east-1のWAFV2とap-northeast-1のCloudFrontを繋ぐためのStack
cross_region_reference_stack = CrossRegionReferenceStack(
app, 'CrossRegionReferenceStack', wafv2_stack,
env=cdk.Environment(region='ap-northeast-1')
)
# ap-northeast-1のStackでCloudFrontを作成する
cloudfront_stack = CloudFrontStack(
app, 'CloudFrontStack', cross_region_reference_stack.webacl_arn,
env=cdk.Environment(region='ap-northeast-1')
)
app.synth()
7. cdkをデプロイ
今回はスタックが3つあるため--allをつけてデプロイコマンドを実行します。
cdk deploy --all
デプロイが完了し、CloudFrontのドメインにアクセスするとベーシック認証画面が表示されます。
ログインすると以下の画面となり、CloudFrontにWAFが紐づいていることが確認できました。
まとめ
今回は異なるリージョンのスタックで作成しているWAFV2とCloudFrontを紐づける方法について紹介しました。ご参考になれば幸いです。