静的ページを作成するためのCloudFormationテンプレート（カスタムドメイン無し）


S3をオリジンにして静的ページを作成したい場合のCloudFormationテンプレート。

カスタムドメインは設定しないので`xxxxx.cloudfront.net`のようなURLのアクセスのみ可能。
本番利用は想定していないので一時的に動作確認したいときとかに使う用です。

S3のバケットポリシーはCloudFront経由のアクセスを許可するための設定になります。

S3バケット名とCloudFrontのTTLは必要に応じて変更したいためパラメータ化しています。
`AWS::WAF::IPSet`に関しては許可したいIPが都度異なるためベタ書き。

## 注意点
こちらのサイトに書かれていますが、作成後は気長に1時間くらい待たないといけないデス:innocent: 

- http://miyasakura.hatenablog.com/entry/2016/12/28/200000
- http://masaru-tech.hateblo.jp/entry/2018/03/27/111327


## テンプレート

```yaml
AWSTemplateFormatVersion: 2010-09-09
Description: Web Site Hosting Stack

Parameters:
  BucketName:
    Type: String
  CloudFrontTTL:
    Type: Number
    Default: 0

Resources:
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      AccessControl: Private
      BucketName: !Ref BucketName
      WebsiteConfiguration:
        IndexDocument: index.html
        ErrorDocument: error.html

  S3BucketPolicy:
    Type: AWS::S3::BucketPolicy
    DependsOn:
      - S3Bucket
      - CloudFrontOriginAccessIdentity
    Properties:
      Bucket: !Ref S3Bucket
      PolicyDocument:
        Version: 2008-10-17
        Statement:
          - Action:
              - s3:GetObject
            Effect: Allow
            Resource: !Join ["/", [!GetAtt S3Bucket.Arn, "*"]]
            Principal:
              AWS: !Sub "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ${CloudFrontOriginAccessIdentity}"

  CloudFrontOriginAccessIdentity:
    Type: AWS::CloudFront::CloudFrontOriginAccessIdentity
    Properties:
      CloudFrontOriginAccessIdentityConfig:
        Comment: !Sub "${BucketName} access identity"

  CloudFrontDistribution:
    Type: AWS::CloudFront::Distribution
    DependsOn:
      - S3Bucket
      - CloudFrontOriginAccessIdentity
      - WebACL
    Properties:
      DistributionConfig:
        Enabled: true
        DefaultCacheBehavior:
          AllowedMethods:
            - HEAD
            - GET
          CachedMethods:
            - HEAD
            - GET
          DefaultTTL: !Ref CloudFrontTTL
          MaxTTL: !Ref CloudFrontTTL
          MinTTL: !Ref CloudFrontTTL
          TargetOriginId: !Sub "${BucketName}-Origin"
          ViewerProtocolPolicy: redirect-to-https
          ForwardedValues:
            QueryString: false
        IPV6Enabled: true
        HttpVersion: http2
        DefaultRootObject: index.html
        WebACLId: !Ref WebACL
        Origins:
          - Id: !Sub "${BucketName}-Origin"
            DomainName: !Sub "${BucketName}.s3.amazonaws.com"
            S3OriginConfig:
              OriginAccessIdentity: !Sub "origin-access-identity/cloudfront/${CloudFrontOriginAccessIdentity}"

  WebACL:
    Type: AWS::WAF::WebACL
    DependsOn:
      - IPSetRule
    Properties:
      DefaultAction:
        Type: BLOCK
      MetricName: WebACLMetric
      Name: !Sub "${BucketName} WebACL"
      Rules:
        - Action:
            Type: ALLOW
          Priority: 0
          RuleId: !Ref IPSetRule

  IPSetRule:
    Type: AWS::WAF::Rule
    Properties:
      Name: !Sub "${BucketName} IPSetRule"
      MetricName: IPSetRuleMetric
      Predicates:
        - DataId: !Ref IPSet
          Negated: false
          Type: IPMatch

  IPSet:
    Type: AWS::WAF::IPSet
    Properties:
      IPSetDescriptors:
        - Type: IPV4
          # ここは書き換える
          Value: aaa.bbb.ccc.ddd/32
      Name: !Sub "${BucketName} IPSet"
```