【CloudFormation】Cloudfront用のAWS WAFを一発作成

本記事では、CloudFormationによる、Cloudfront用のAWS WAFをコード付きで解説します。

S3 Bucket Policy

前提

バージニア北部(N.Verginia)で作成が必要。

実際のコード

AWSTemplateFormatVersion: "2010-09-09"
Description: WAF for CloudFront

Parameters:
  System:
    Type: String
    Default: test-system
  Env:
    Type: String
    Default: test

Resources:
# ------------------------------------------------------------#
# Cloudwatch Logs Log Group 
# ------------------------------------------------------------#
  WAFLogGroup:
    Type: AWS::Logs::LogGroup
    Properties: 
      LogGroupName: !Sub aws-waf-logs-${System}-${Env}-web-acl-CloudFront

# ------------------------------------------------------------#
# WAF v2
# ------------------------------------------------------------#
  # WAF WebACL
  WebAcl:
    Type: AWS::WAFv2::WebACL
    Properties:
      DefaultAction:
        Allow: {}
      Name: !Sub ${System}-${Env}-web-acl-CloudFront
      # Rules
      Rules:
        -
          Name: IpReputationList
          Priority: "0"
          OverrideAction:
            Count: {}
          VisibilityConfig:
            SampledRequestsEnabled: True
            CloudWatchMetricsEnabled: True
            MetricName: !Sub ${System}-${Env}-CloudFront-IpReputationListMetric
          Statement:
            ManagedRuleGroupStatement:
              VendorName: AWS
              Name: AWSManagedRulesAmazonIpReputationList
              ExcludedRules: []
        -
          Name: AnonymousIpList
          Priority: "1"
          OverrideAction:
            Count: {}
          VisibilityConfig:
            SampledRequestsEnabled: True
            CloudWatchMetricsEnabled: True
            MetricName: !Sub ${System}-${Env}-CloudFront-AnonymousIpListMetric
          Statement:
            ManagedRuleGroupStatement:
              VendorName: AWS
              Name: AWSManagedRulesAnonymousIpList
              ExcludedRules: []              
        -
          Name: CommonRuleSet
          Priority: "2"
          OverrideAction:
            Count: {}
          VisibilityConfig:
            SampledRequestsEnabled: True
            CloudWatchMetricsEnabled: True
            MetricName: !Sub ${System}-${Env}-CloudFront-CommonRuleSetMetric
          Statement:
            ManagedRuleGroupStatement:
              VendorName: AWS
              Name: AWSManagedRulesCommonRuleSet
              ExcludedRules: 
                - Name: SizeRestrictions_BODY
        -
          Name: KnownBadInputsRuleSet
          Priority: "3"
          OverrideAction:
            Count: {}
          VisibilityConfig:
            SampledRequestsEnabled: True
            CloudWatchMetricsEnabled: True
            MetricName: !Sub ${System}-${Env}-CloudFront-KnownBadInputsRuleSetMetric
          Statement:
            ManagedRuleGroupStatement:
              VendorName: AWS
              Name: AWSManagedRulesKnownBadInputsRuleSet
              ExcludedRules: []     
        -
          Name: RateBaseRuleSet
          Priority: "4"
          OverrideAction:
            None: {}
          VisibilityConfig:
            SampledRequestsEnabled: True
            CloudWatchMetricsEnabled: True
            MetricName: !Sub ${System}-${Env}-CloudFront-RateBaseRuleSetMetric
          Statement:
            RuleGroupReferenceStatement: 
              Arn: !GetAtt CloudFrontRuleGroup.Arn                            
      Scope: CLOUDFRONT
      VisibilityConfig:
        SampledRequestsEnabled: True
        CloudWatchMetricsEnabled: True
        MetricName: !Sub ${Env}WebACLCloudFrontMetric

  CloudFrontRuleGroup:
    Type: AWS::WAFv2::RuleGroup
    Properties:
      Capacity: '100'
      Name: !Sub ${System}-${Env}-rulegroup-CloudFront
      Rules:

  # Rate Base Block
        - Name: !Sub ${System}-${Env}-waf-rate-base-block
          Priority: '5'
          Action: 
            Block: {}
          Statement:
            RateBasedStatement:
              Limit: '300'
              AggregateKeyType: IP
          VisibilityConfig:
            SampledRequestsEnabled: 'True'
            CloudWatchMetricsEnabled: 'True'
            MetricName: !Sub ${System}-${Env}-waf-rate-base-block-Metric
      Scope: CLOUDFRONT
      VisibilityConfig:
        SampledRequestsEnabled: 'True'
        CloudWatchMetricsEnabled: 'True'
        MetricName: WebACLCloudFrontRuleGroup01Metric

# Logsへの格納
  WAFLogConfig:
    Type: AWS::WAFv2::LoggingConfiguration
    Properties:
      LogDestinationConfigs:
        - !GetAtt WAFLogGroup.Arn
      ResourceArn: !GetAtt WebAcl.Arn