【CloudFormation】Cloudfront+S3でSorryページを一発で作成する

本記事では、CloudFormationによる、Cloudfront+S3でSorryページの作成について、コード付きで解説します。

S3 Bucket Policy

前提

ログ送信用のバケット、証明書とWAFは事前に作成済みであること。

※ログ送信用バケットの名前は、s3-logとし、ACLを許可しておく必要がある。

※ACM(証明書)、AWS WAFのみバージニア北部(N.Verginia)で作成が必要。

説明

パラメーターのうち、DomainとWebACLIdのみ変更必要。

実際のコード

AWSTemplateFormatVersion: 2010-09-09

Parameters:
  Env:
    Type: String
    Default: test
  System:
    Type: String
    Default: test-system
  Region:
    Type: String
    Default: tokyo        
  SSLId:
    Type: String
    Default: <SSLId>
  Domain: 
    Type: String
    Default: www.test.com
  WebACLId: 
    Type: String
    Default: arn:aws:wafv2:us-east-1:<Account ID>:global/webacl/<WebACL Name>/<ID>                 

Resources:
  #-----------------------------------------------------------------------------
  # S3 bucket
  #-----------------------------------------------------------------------------
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub ${Domain} #ドメイン名とバケット名は同じにする

  S3BucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref S3Bucket
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Action:
              - s3:GetObject
            Effect: Allow
            Resource:
              - !Sub arn:aws:s3:::${S3Bucket}/*
            Principal:
              Service: cloudfront.amazonaws.com
            Condition:
              StringEquals:
                AWS:SourceArn: !Sub arn:aws:cloudfront::${AWS::AccountId}:distribution/${CloudFrontDistribution}

  #-----------------------------------------------------------------------------
  # CloudFront 
  #-----------------------------------------------------------------------------
  CloudFrontDistribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        Comment: !Sub ${System}-${Env}-Cloudfront-distribution
        Origins:
          - DomainName: !GetAtt S3Bucket.RegionalDomainName
            Id: S3Origin
            OriginAccessControlId: !GetAtt OAC.Id
            S3OriginConfig:
              OriginAccessIdentity: ''
        Enabled: true
        DefaultRootObject: maintenance.html #S3バケットのルートに配置する
        DefaultCacheBehavior:
          TargetOriginId: S3Origin
          Compress: true
          ForwardedValues:
            QueryString: false
            Cookies:
              Forward: none
          CachePolicyId: 658327ea-f89d-4fab-a63d-7e88639e58f6  # S3に対して利用する場合はこれが推奨されている
          ViewerProtocolPolicy: redirect-to-https
          AllowedMethods:
            - GET
            - HEAD
          CachedMethods:
            - GET
            - HEAD
        PriceClass: PriceClass_200 #100ではアジアが含まれない。Allは全リージョン。
        Logging:
              Bucket: s3-log.s3.amazonaws.com #S3へログを送付する場合
              IncludeCookies: false
              Prefix: cloudfront/
        HttpVersion: http2and3 #全httpバージョンに適応するため
        Aliases:
          - !Sub "${Domain}"
        ViewerCertificate:
          SslSupportMethod: sni-only
          MinimumProtocolVersion: TLSv1.2_2021
          AcmCertificateArn: !Sub arn:aws:acm:us-east-1:${AWS::AccountId}:certificate/${SSLId}
        WebACLId: !Sub ${WebACLId}      

  OAC:
    Type: AWS::CloudFront::OriginAccessControl
    Properties:
      OriginAccessControlConfig:
        Description: Access Control
        Name: !Sub ${System}-${Env}oac
        OriginAccessControlOriginType: s3
        SigningBehavior: always
        SigningProtocol: sigv4