【AWS】CloudFormtionでブログサービスを構築してみた(05.Waf編)

# 01.はじめに
[【AWS】CloudFormtionでブログサービスを構築してみた(概要編)](https://qiita.com/1k5/items/4f6d61373e80f824bd9a)の最終回である。
過去に公開した記事は下記の通りである。
・[【AWS】CloudFormtionでブログサービスを構築してみた(概要編)](https://qiita.com/1k5/items/4f6d61373e80f824bd9a)
・[【AWS】CloudFormtionでブログサービスを構築してみた(01.Network編)](https://qiita.com/1k5/items/d268697691ef2ef3dd0e)
・[【AWS】CloudFormtionでブログサービスを構築してみた(02.EC2,RDS,ALB編)](https://qiita.com/1k5/items/5acca0ee627ec37b56da)
・[【AWS】CloudFormtionでブログサービスを構築してみた(03.S3,CloudFront編)](https://qiita.com/1k5/items/a19cb65bb749b985970c)
・[【AWS】CloudFormtionでブログサービスを構築してみた(04.Route53編)](https://qiita.com/1k5/items/96c7874050e4bb9a5127)

# 02.構成図
構成図はこちらである。(これでゴール)
![構成図2-WAF.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050566/60a92da6-9336-0301-ae94-380da096ecf7.png)


ここまでの設定で独自ドメインでアクセス出来て、障害発生時にはSorryページに通信を流すことが出来た。
ただ、IPアドレス直接アクセスはセキュリティ的にあまりよろしくないので、
IPアドレスでアクセスしてきた通信を遮断する設定をWafで入れる。
特定のIPではなく全てのIPアドレスを遮断する。(ALBはIP変わることあるため)

# 03.事前確認
現在の設定はIPアドレスでアクセス出来てしまう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050566/5d387f25-88bf-729b-1126-c9f858fecdd9.png)

# 04.テンプレートファイル
Outputs情報
```yaml
Outputs:
#ALBのARNの定義(WAFで使う)
  ALBArn:
      Value: !Ref CFALB
      Export:
        Name: ALB-ARN-Outputs 
```

```yaml:waf.yml
AWSTemplateFormatVersion: 2010-09-09
Description: Waf-ACL

Resources:
# ------------------------------------------------------------#
# IPブロックリスト
# ------------------------------------------------------------#
  IPBlockList:
    Type: AWS::WAFv2::RegexPatternSet
    Properties:
      Name: IP_regex_pattern_set
      RegularExpressionList:
        - (([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])
      Scope: REGIONAL

# ------------------------------------------------------------#
# WebACLAssociation
# ------------------------------------------------------------#
  WebACLAssociation:
    Type: AWS::WAFv2::WebACLAssociation
    Properties:
      ResourceArn: !ImportValue ALB-ARN-Outputs
      WebACLArn: 
        Fn::GetAtt: WebACL.Arn

# ------------------------------------------------------------#
# WebACL
# ------------------------------------------------------------#
  WebACL:
    Type: AWS::WAFv2::WebACL
    Properties: 
      DefaultAction: 
        Allow: {}
      Description: WebACL
      Name: WebACL
      Rules: 
        - Name: IPBlock
          Action:
            Block: {}
          Priority: 0
          Statement:
            RegexPatternSetReferenceStatement:
              Arn: !GetAtt IPBlockList.Arn
              FieldToMatch: 
                SingleHeader: host
              TextTransformations: 
                - Type: "NONE"
                  Priority: 100
          VisibilityConfig: 
            CloudWatchMetricsEnabled: true
            MetricName: "MyWAFWebACLMetrics"
            SampledRequestsEnabled: true
      Scope: REGIONAL
      VisibilityConfig: 
        CloudWatchMetricsEnabled: true
        MetricName: "MyWAFWebACLMetrics-CF"
        SampledRequestsEnabled: true
```

# 05.テストアクセス
先ほどと同じ通信先にアクセスしたらブロックされた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050566/8a3d9ca7-1e32-7fa3-48ff-7658e3b11c20.png)

# 06.最後に
色々エラーや想定外が起こって大変だったが、無事に当初の構想通りに構築できた。

ただ、ALB周りの設計がなかなか大変で細かい設定を入れるくらいならCloudFrontの
オリジンフェイルオーバーで運用したほうが想定外の発生が起きづらいのではないかと思った。
(もちろん仕様をしっかり理解している前提だが)

また、EC2、RDSのスペックも無料枠で利用できるスペックなのでアクセス負荷の面でも一考の余地があるのではないかと思った。


今後は
・EC2をコンテナ化する
・CloudWatchを入れて実運用の監視をする
・同様の構成をCloudFrontのオリジンフェイルオーバーで実装してみる

等を試してみたい。

# 参考文献
https://dev.classmethod.jp/articles/tsnote-alb-waf-ip-request-block/

https://qiita.com/miyabiz/items/9b5da901601e947114ec