[アップデート] AWS CDK で CloudFront Distribution の作成後に Web ACL をアタッチ可能になりました

[アップデート] AWS CDK で CloudFront Distribution の作成後に Web ACL をアタッチ可能になりました

Clock Icon2024.11.21

こんにちは、製造ビジネステクノロジー部の若槻です。

AWS CDK の最新のリリースである v2.169.0 で、下記の機能アップデートが追加されていました。

cloudfront: add attachWebAclId method for Distribution (#30567) (cbe2bec)

CDK で CloudFront DistributionAWS WAF Web ACL をアタッチする場合は、もともとは webAclId プロパティを使って宣言的に行う必要がありましたが、今回のアップデートで attachWebAclId メソッドが追加され、手続き的にも行えるようになりました。

これにより Distribution の作成後に WebACL をアタッチできるようになり、カスタムコンストラクトの構成もより柔軟に実装できるようになりました。

試してみた

CDK パッケージのアップデート

AWS CDK モジュールを v2.169.0 以上にアップデートします。

npm i aws-cdk-lib@latest aws-cdk@latest

CDK コード

以下のような CDK コードで attachWebAclId メソッドを使って CloudFront Distribution に WebACL をアタッチしてみます。WebACL の指定は今まで通り Arn で行います。

lib/main-stack.ts
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';
import * as origins from 'aws-cdk-lib/aws-cloudfront-origins';
import * as wafv2 from 'aws-cdk-lib/aws-wafv2';

export class MainStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props: cdk.StackProps) {
    super(scope, id, props);

    // CloudFront Distribution
    const distribution = new cloudfront.Distribution(this, 'Distribution', {
      defaultBehavior: {
        origin: new origins.HttpOrigin('classmethod.jp'),
      },
      // webAclId: webAcl.attrArn, // 以前まではこのように Distribution 作成時に WebACL をアタッチする方法のみだった
    });

    // AWS WAFv2 WebACL
    const webAcl = new wafv2.CfnWebACL(this, 'WebAcl', {
      scope: 'CLOUDFRONT',
      defaultAction: { allow: {} },
      visibilityConfig: {
        cloudWatchMetricsEnabled: true,
        metricName: 'webACL',
        sampledRequestsEnabled: true,
      },
      rules: [],
    });

    // CloudFront Distribution に WebACL をアタッチ
    distribution.attachWebAclId(webAcl.attrArn);
  }
}

デプロイ前に cdk diff で差分を確認すると、WebACL が Distribution にアタッチされることが確認できます。

$ npx cdk diff Main
start: Building 27e445a130d4f4553a04ed2a11e6f447d55a5ee7ee1dc2211971188b3fcbe293:XXXXXXXXXXXX-us-east-1
success: Built 27e445a130d4f4553a04ed2a11e6f447d55a5ee7ee1dc2211971188b3fcbe293:XXXXXXXXXXXX-us-east-1
start: Publishing 27e445a130d4f4553a04ed2a11e6f447d55a5ee7ee1dc2211971188b3fcbe293:XXXXXXXXXXXX-us-east-1
success: Published 27e445a130d4f4553a04ed2a11e6f447d55a5ee7ee1dc2211971188b3fcbe293:XXXXXXXXXXXX-us-east-1
Hold on while we create a read-only change set to get a diff with accurate replacement information (use --no-change-set to use a less accurate but faster template-only diff)
Stack Main
Resources
[~] AWS::CloudFront::Distribution Distribution Distribution830FAC52
 └─ [~] DistributionConfig
     └─ [+] Added: .WebACLId


✨  Number of stacks with differences: 1

デプロイを行い、Distribution のセキュリティ設定を確認すると、WebACL がアタッチされていることが確認できました。

トラブルシュート

デプロイ時に次のようなエラーが発生しました。

$ npm run deploy -- Main

> cdk_sample_app@0.1.0 deploy
> cdk deploy --require-approval never --method=direct Main


✨  Synthesis time: 4.75s

Main: deploying... [1/1]
Main: updating stack...
10:10:26 PM | CREATE_FAILED        | AWS::WAFv2::WebACL            | WebAcl
Resource handler returned message: "Error reason: The scope is not valid., field: SCOPE_VALUE, parameter: CLOUDFRONT (Service: Wafv2, Status Code: 400, Request ID: 9
8b508f1-626c-4922-87ad-5e1341bb6029)" (RequestToken: 1de0e851-bc87-21c5-4fe3-994251e5f14a, HandlerErrorCode: InvalidRequest)

間違えて ue-east-1 (バージニア北部) ではなく ap-northeast-1 で WebACL を作成していたためでした。CloudFront + WAF の組み合わせで触るのは久し振りだったので若干ハマりました。

今回のアップデートとはあまり関係ないエラーではあるのですが、CloudFront を利用するシステムを構築する際には意識しておきたいポイントなので、共有させていただきました。

参考

https://dev.classmethod.jp/articles/cloudformation-webacl-cloudfront-error/#Error%2520reason%253A%2520The%2520scope%2520is%2520not%2520valid.%252C%2520field%253A%2520SCOPE_VALUE%252C%2520parameter%253A%2520CLOUDFRONT

おわりに

AWS CDK で CloudFront Distribution の作成後に Web ACL をアタッチ可能になったので共有しました。

素の CloudFormation を利用することに対する CDK の強みは今回のような手続き的なメソッドで IaC を記述できる点だと思うので、このようなアップデートはとても嬉しいですね。

以上

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.