【AWS×Webアプリ】CloudFront＋S3静的Webサイトホスティング（SAM）

## 目的
・AWS上の静的Webサイトホスティングを有効にしたS3をCloudFrontで公開。
・OAC（OriginAccessControl）を使用したアクセス制限。

## 前提条件
・SAMを使用してAWS上にリソースを作成する。

## 完成イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637963/2201b8a3-1bb2-3a79-9bb4-c475ebde7453.png)

## SAMテンプレート
```yaml:template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Resources:
  WebBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub ${AWS::StackName}-webbucket-${AWS::AccountId}
      VersioningConfiguration:
        Status: Enabled
      WebsiteConfiguration:
        IndexDocument: index.html
      PublicAccessBlockConfiguration:
        IgnorePublicAcls: false
  WebBucketBucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref WebBucket
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Principal:
              Service: cloudfront.amazonaws.com
            Action:
              - s3:GetObject
            Effect: Allow
            Resource:
              - !Sub ${WebBucket.Arn}/*
            Condition:
              StringEquals:
                AWS:SourceArn:
                  - !Sub arn:aws:cloudfront::${AWS::AccountId}:distribution/${WebBucketDistribution}
  WebBucketDistribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        DefaultCacheBehavior:
          TargetOriginId: WebBucketOrigin
          Compress: true
          ViewerProtocolPolicy: redirect-to-https
          AllowedMethods:
            - GET
            - HEAD
          CachedMethods:
            - GET
            - HEAD
          CachePolicyId: !Ref WebBucketCachePolicy
          OriginRequestPolicyId: !Ref WebBucketOriginRequestPolicy
        PriceClass: PriceClass_200
        DefaultRootObject: index.html
        Enabled: true
        Origins:
          - DomainName: !GetAtt WebBucket.RegionalDomainName
            Id: WebBucketOrigin
            OriginAccessControlId: !GetAtt WebBucketOriginAccessControl.Id
            S3OriginConfig:
              OriginAccessIdentity: ''
  WebBucketOriginAccessControl:
    Type: AWS::CloudFront::OriginAccessControl
    Properties:
      OriginAccessControlConfig:
        SigningBehavior: always
        OriginAccessControlOriginType: s3
        SigningProtocol: sigv4
        Name: !Sub ${AWS::StackName}-OAC-${AWS::AccountId}
  WebBucketCachePolicy:
    Type: 'AWS::CloudFront::CachePolicy'
    Properties:
      CachePolicyConfig:
        Name: WebBucketCachePolicy
        DefaultTTL: 86400
        MaxTTL: 31536000
        MinTTL: 3600
        ParametersInCacheKeyAndForwardedToOrigin:
          EnableAcceptEncodingGzip: true
          EnableAcceptEncodingBrotli: true
          CookiesConfig:
            CookieBehavior: none
          HeadersConfig:
            HeaderBehavior: none
          QueryStringsConfig:
            QueryStringBehavior: none
  WebBucketOriginRequestPolicy:
    Type: 'AWS::CloudFront::OriginRequestPolicy'
    Properties:
      OriginRequestPolicyConfig:
        Name: WebBucketOriginRequestPolicy
        CookiesConfig:
          CookieBehavior: none
        HeadersConfig:
          HeaderBehavior: none
        QueryStringsConfig:
          QueryStringBehavior: none
Outputs:
  WebsiteURLonS3:
    Description: URL for website hosted on S3
    Value: !GetAtt WebBucket.WebsiteURL
  WebsiteURLonCF:
    Description: URL for website hosted on CloudFront
    Value: !GetAtt WebBucketDistribution.DomainName
```

①WebBucket（S3バケット）
・前回記事より設定内容に変更なし

②WebBucketBucketPolicy（バケットポリシー）
・CloudFront経由でのアクセス（s3:GetObject）のみ許可

③WebBucketDistribution（CloudFrontディストリビューション）
・DefaultCacheBehavior：デフォルトのキャッシュ動作
　a. HTTPリクエストを自動的に HTTPSリクエストにリダイレクト
 （ViewerProtocolPolicy: redirect-to-https）
　b. GET/HEADメソッドのみ処理（AllowedMethods: ～）
　c. GET/HEADメソッドのみレスポンスをキャッシュ（CachedMethods: ～）
・PriceClass：料金クラスの設定
・Enabled：ディストリビューションの有効化
・Origins：オリジンの設定 
　a. DomainName：オリジンのドメイン名（①WebBucketのドメイン名を指定）
　b. OriginAccessControlId：OACのID（④WebBucketOriginAccessControlのIDを指定）
　c. S3OriginConfig：OACを使用する場合の設定（OriginAccessIdentity: ''）

④WebBucketOriginAccessControl（OAC）
・OriginAccessControlConfig：OACの設定
　a. すべてのオリジンリクエストに認証情報を追加（SigningBehavior: always）
　b. OACの署名プロトコル（SigningProtocol: sigv4）

⑤WebBucketCachePolicy（キャッシュポリシー）

⑥WebBucketOriginRequestPolicy（オリジンリクエストポリシー）

## 動作確認
①Webサイトへアクセス（S3）
・アクセスできないことを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637963/c20b0e5c-7627-899d-519d-befa60c9ef66.png)

②Webサイトへアクセス（CloudFront）
・正常にアクセスできることを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637963/eab6d3db-404e-2453-8336-21e4b2ac07d0.png)

## 参考（前回記事）
https://qiita.com/Haruki-N/items/68661c410bb4a143183a