0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

複数のスタックから参照されるAWS WAFのWebACLを書いた (CDK)

Posted at

はじめに

API Gatewayに対してAWS WAFを使ってみよう、と思い立ち、こちらのページを参考にしてCDKで構築してみました。

このページで紹介いただいているスタックは、WebACLの作成とリソースの紐付けを1つのスタック内に持っているのですが、

  • リソースごとにWebACLを作るより1つのWebACLを複数のリソースと紐づける方が料金的に有利
  • 複数のリソースでWebACLを使い回すことを考えると、WebACLと同じスタック内で紐付けを行う形をとると使い勝手が悪い

という事情により、WebACLを定義するWAF部分を1つのスタック、紐付けはWebACLを利用するリソースを含むスタック、という構成で使えるように変更してみました。

WAF部分

WebACLに加えてWebACLのARNを格納するパラメータストアを含むスタックにしています。
S3用のバケットは以下コードでは含めてないですが、必要に応じてお好きにどうぞ…

実際のコードから抜粋しているので、このままだと動かないかもですが、見て欲しいところは「WebAclのARNを格納するパラメータストア」というコメントが入っている箇所になります。

なお、スタックの上位側(binディレクトリに置いてあるコード)の方からパラメータストア名を渡して使う形にしています。

waf-stack.ts
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';

type WafStackProps = cdk.StackProps & {
  webAclArnParameterName: string;
};

export class WafStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props: WafStackProps) {
    super(scope, id, props)

    // WAF Web ACL
    const webAcl = new cdk.aws_wafv2.CfnWebACL(this, "wafV2WebAcl", {
      defaultAction: { allow: {} },
      scope: "REGIONAL",
      visibilityConfig: {
        cloudWatchMetricsEnabled: true,
        sampledRequestsEnabled: true,
        metricName: "wafV2WebAcl",
      },
      rules: [
        {
          name: "AWSManagedRulesCommonRuleSet",
          priority: 1,
          statement: {
            managedRuleGroupStatement: {
              vendorName: "AWS",
              name: "AWSManagedRulesCommonRuleSet",
            },
          },
          overrideAction: {
            none: {}
          },
          visibilityConfig: {
            cloudWatchMetricsEnabled: true,
            sampledRequestsEnabled: true,
            metricName: "AWSManagedRulesCommonRuleSet",
          },
        },
	// 必要なルールセットはここに追加
      ],
    });

    // WebAclのARNを格納するパラメータストア
    new cdk.aws_ssm.StringParameter(this, 'wafV2WebAclArnParameter', {
      parameterName: props.webAclArnParameterName,
      stringValue: webAcl.attrArn,
    });
  }
}

せっかくのCDKなのに、WAFはL1 constructsしか使えないのがしんどいですね。

WAFを使う側

せっかくCDKでWAF側を書いたのですが、現在使う側はSAMで書かれているAPI Gatewayのみの状況のため、SAMテンプレートの抜粋を記述しておきます。
テンプレートパラメータWafWebAclArnに上のスタックで作成したパラメータストアの名前を指定する形になります。

template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Parameters:
  WafWebAclArn:
    Type: 'AWS::SSM::Parameter::Value<String>'
Resources:
  ApiFunction:
    Type: AWS::Serverless::Function
    Properties:
      # いろいろ書く
  Api:
    Type: AWS::Serverless::Api
    Properties:
      StageName: Prod
      EndpointConfiguration:
        Type: REGIONAL
      # いろいろ書く
  WebAclAssociation:
    Type: AWS::WAFv2::WebACLAssociation
    Properties:
      ResourceArn: !Sub 'arn:aws:apigateway:${AWS::Region}::/restapis/${Api}/stages/Prod'
      WebACLArn: !Ref WafWebAclArn
    DependsOn: Api

使っているのはパラメータストアなので、CDKでもStringParameter.valueForStringParameterを使って実現可能です。こちらのページをご参照ください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?