大田区から発信するゆるゆる日記

主にITエンジニアに関する備忘録日記。たまに趣味も。何か不備があればコメント頂けると幸いです。Twitterアカウント https://twitter.com/ryuzan03

【CloudFormation】CloudFrontのオリジンアクセスコントロール(OAC)でS3(SPA)へのアクセスを制限する

※下記の内容に不備がありましたら、コメント頂けると幸いです。また、下記の内容をご使用頂ける場合は自己責任でお願いします。

概要

2022年8月25日にAmazon CloudFrontでOrigin Access Control(OAC)がリリースされました。
Amazon CloudFront でオリジンアクセスコントロール (OAC) をリリース

これにより、従来のOrigin Access Identity(OAI)は「legacy, not recommended」と記載されるようになっています(コンソールの設定画面では「Legacy access identifies」)。

せっかくなので、今回はCloudFormationでS3(SPA)+CloudFront(OAC)の構成を作成してみたいと思います。

内容

S3+CloudFrontで静的サイト(SPA)をホスティングするメリット

  • CloudFront経由でのアクセスに制限できる(OAC)
  • キャッシュによる表示速度の高速化
  • WAFの設定が可能
  • 独自ドメインSSL化が可能

CloudFormationでS3+CloudFront(OAC)を作成

下記で作成したS3バケット(bucket-name)にビルドしたコードをアップロードすると、CloudFrontのディストリビューションドメインからSPAにアクセスが可能になります。

Resources:
  # ------------------------------------------------------------#
  #  S3 Bucket
  # ------------------------------------------------------------#
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketEncryption:
        ServerSideEncryptionConfiguration:
          - ServerSideEncryptionByDefault:
              SSEAlgorithm: AES256
      BucketName: bucket-name
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true

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

  # ------------------------------------------------------------#
  #  CloudFront
  # ------------------------------------------------------------#
  CloudFrontDistribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        CustomErrorResponses:
          - ErrorCachingMinTTL: 10
            ErrorCode: 403
            ResponseCode: 200
            ResponsePagePath: /index.html
          - ErrorCachingMinTTL: 10
            ErrorCode: 404
            ResponseCode: 200
            ResponsePagePath: /index.html
        DefaultCacheBehavior:
          TargetOriginId: !Sub origin-${S3Bucket}
          Compress: true
          ViewerProtocolPolicy: redirect-to-https
          AllowedMethods:
            - GET
            - HEAD
          CachedMethods:
            - GET
            - HEAD
          CachePolicyId: 658327ea-f89d-4fab-a63d-7e88639e58f6
        DefaultRootObject: index.html
        Enabled: true
        HttpVersion: http2and3
        Origins:
          - Id: !Sub origin-${S3Bucket}
            DomainName: !GetAtt S3Bucket.RegionalDomainName
            OriginAccessControlId: !Ref CloudFrontOriginAccessControl
            S3OriginConfig:
              OriginAccessIdentity: ""
        PriceClass: PriceClass_All

  # Origin Access Control(OAC)
  CloudFrontOriginAccessControl:
    Type: AWS::CloudFront::OriginAccessControl
    Properties:
      OriginAccessControlConfig:
        Description: OAC for S3 Bucket
        Name: origin-access-control-name
        OriginAccessControlOriginType: s3
        SigningBehavior: always
        SigningProtocol: sigv4



ErrorPages(エラーページ)を使用せずにS3(SPA)+CloudFront(OAC)のURLで自然にページを表示させたい

下記の記事が参考になりそうです。
AWSのCloudFront+S3でSPAするときにErrorPagesを使いたくない | AreaB Blog

S3(SPA)+CloudFront(OAC)+WAF v2

上記のCFnで作成したAWSリソースにWAFを設置して403エラーを返す場合がややこしく、WAF v2を使用して403エラーを403・404エラー以外を返すようにレスポンスをカスタマイズする必要があります。
【AWS】S3+CloudFrontでSPA対応する方法とWAFのIP制限干渉を解決する方法! | しーまんブログ

参考

素晴らしい記事に感謝致します。
Amazon CloudFront でオリジンアクセスコントロール (OAC) をリリース
Amazon CloudFront オリジンアクセスコントロール(OAC)のご紹介 | Amazon Web Services ブログ
AWS::CloudFront::OriginAccessControl - AWS CloudFormation
Restricting access to an Amazon S3 origin - Amazon CloudFront
[NEW] CloudFrontからS3への新たなアクセス制御方法としてOrigin Access Control (OAC)が発表されました! | DevelopersIO
【AWS】S3+CloudFrontでSPA対応する方法とWAFのIP制限干渉を解決する方法! | しーまんブログ
AWSのCloudFront+S3でSPAするときにErrorPagesを使いたくない | AreaB Blog