4
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.

分析屋が異世界転生してエンジニアになったAdvent Calendar 2022

Day 13

WAFv2+S3+CloudFrontの構成をCloudFormationでつくる

Last updated at Posted at 2022-12-12

はじめに

CloudFrontのWAFv2設定をIaCしたので簡単にまとめてみます。

つくりかた

① waf.ymlのスタック作成(下記IaC参照)
② 「出力」からWebACLのARNをコピー
image.png

③ cloudfront.ymlのスタック作成時にコピーしてきたARNを入力(下記IaC参照)
image.png

IaC

waf.yml
AWSTemplateFormatVersion: "2010-09-09"
Description: WAF for Cloud Front
Parameters:
  ProjectName:
    Description: Type of this ProjectName.
    Type: String
Resources:
  # ------------------------------------------------------------#
  #  WebACL for CloudFront
  # ------------------------------------------------------------#
  WebACL:
    Type: AWS::WAFv2::WebACL
    Properties:
      Name: !Sub "${ProjectName}WebACL"
      Scope: CLOUDFRONT
      DefaultAction:
        Block: {}
      VisibilityConfig:
        SampledRequestsEnabled: true
        CloudWatchMetricsEnabled: true
        MetricName: webaclcloudfront
      Rules:
        - Name: !Sub "${ProjectName}aclrules"
          Priority: 0
          Action:
            Allow: {}
          Statement:
            IPSetReferenceStatement:
              Arn: !GetAtt WAFIPSet.Arn
          VisibilityConfig:
            SampledRequestsEnabled: true
            CloudWatchMetricsEnabled: true
            MetricName: !Sub "${ProjectName}aclrules"

  # ------------------------------------------------------------#
  #  IPSet for WAF
  # ------------------------------------------------------------#
  WAFIPSet:
    Type: AWS::WAFv2::IPSet
    Properties:
      Name: !Sub "${ProjectName}"
      Scope: CLOUDFRONT
      IPAddressVersion: IPV4
      # アクセスを許可するIPアドレスを指定
      Addresses:
        - "--.--.--.--/32"
        - "--.--.--.--/32"
Outputs:
  WebACLArn:
    Value: !GetAtt WebACL.Arn
cloudfront.yml
AWSTemplateFormatVersion: "2010-09-09"
Description: Create S3 and CloudFront
Parameters:
  ProjectName:
    Description: Type of this ProjectName.
    Type: String
  BucketName:
    Description: Type of this BacketName.
    Type: String
  WebACLArn:
    Type: String

Resources:
  # ------------------------------------------------------------#
  #  S3 Policy for CloudFront
  # ------------------------------------------------------------#
  BucketPolicy:
    Type: "AWS::S3::BucketPolicy"
    Properties:
      Bucket: !Ref Bucket
      PolicyDocument:
        Statement:
          - Action:
              - "s3:GetObject"
            Effect: Allow
            Resource: !Sub "arn:aws:s3:::${BucketName}/*"
            Principal:
              AWS: !Sub "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ${CloudFrontOriginAccessIdentity}"

  # ------------------------------------------------------------#
  #  S3 Bucket
  # ------------------------------------------------------------#
  Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub ${BucketName}
      PublicAccessBlockConfiguration:
        BlockPublicAcls: True
        BlockPublicPolicy: True
        IgnorePublicAcls: True
        RestrictPublicBuckets: True
      AccessControl: Private

  # ------------------------------------------------------------#
  #  CloudFront Distribution
  # ------------------------------------------------------------#
  AssetsDistribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        WebACLId: !Sub ${WebACLArn}
        Origins:
          - Id: S3Origin
            DomainName:
              Fn::GetAtt: Bucket.DomainName
            S3OriginConfig:
              OriginAccessIdentity: !Sub "origin-access-identity/cloudfront/${CloudFrontOriginAccessIdentity}"
        Enabled: true
        DefaultRootObject: index.html
        Comment: !Sub ${AWS::StackName} distribution
        DefaultCacheBehavior:
          TargetOriginId: S3Origin
          ForwardedValues:
            QueryString: false
          ViewerProtocolPolicy: redirect-to-https
        CustomErrorResponses:
          - ErrorCode: 403
            ResponsePagePath: /
            ResponseCode: 200
            ErrorCachingMinTTL: 0
  CloudFrontOriginAccessIdentity:
    Type: AWS::CloudFront::CloudFrontOriginAccessIdentity
    Properties:
      CloudFrontOriginAccessIdentityConfig:
        Comment: !Sub ${AWS::StackName}

つまづいたこと

  • WAFv2を利用する際はリージョンをus-east-1(バージニア)に指定する必要があった
    • cloudformationの画面でリージョンを変更してからスタックの作成をする必要がある

  • スタックの作成順はWAF→CloudFront
    • WAFにはCloudFrontを参照できるプロパティがないため、先にWAFを作成しCloudFront側から関連付ける必要がある(AWS::CloudFront::DistributionのDistributionConfigで関連付けています)

おわりに

コンソールで環境を立てた際は難しさを感じなかったのですが、思ったより時間がかかってしまいました。
公式ドキュメントを読みながら必要な項目を確認し、まずは自分で雛形を作ることが大事でした。

参考

4
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
4
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?