~その1~ Block public accessが自動有効、ACLが自動無効になった事でServerless Frameworkでのバケット新規作成時にハマったこと

2023.06.05

S3バケットは2023年4月以降、新たにバケットを作成する際にBlock public access(BPA)が自動有効になり、Access Control List(ACL)は自動無効になります。

Serverless frameworkを用いたS3バケットの作成の際に、この影響に対する対処が必要だったのですが、対処していない場合に発生するエラーからは原因が分かりづらくハマったので、ブログにどう対処したか残します。

具体的には以下2つの点で対処が必要でした。

  1. パブリックなアクセスが可能になるバケットポリシーを追加するにはBlockPublicPolicyをfalseに設定する必要が有る
  2. CloudFrontのログバケットのACLを有効にするために serverless.ymlに明示的に有効化の記述が必要となっていた

こちらのブログでは1.のパブリックなアクセスが可能になるバケットポリシーを追加するにはBlockPublicPolicyをfalseに設定する必要が有るについて書いていきます。
後日リリース予定の別のブログで2.のCloudFrontのログバケットのACLを有効にするために serverless.ymlに明示的に有効化の記述が必要となっていたについて書きたいと思います。

パブリックなアクセスが可能になるバケットポリシーを追加するにはBlockPublicPolicyをfalseに設定する必要が有る

やりたかったこと

作成したいS3バケットにはバケットポリシーを追加する必要が有りました。
このポリシーのPrincipalの設定は"*"としているため、パブリックなアクセスが可能になるバケットポリシーとなります。

対処前のserverless.yml

対処前は以下のような形でresources:配下にバケットとバケットポリシーに関する記述をしてserverless.ymlを作成しました。 Block public accessについては特に設定してない状態です。

serverless.yml

resources:
  Resources:
    PbaAclTestBucket:
        Type: AWS::S3::Bucket
        Properties:
          BucketName: pba-acl-test-bucket

    PbaAclTestBucketPolicy:
      Type: AWS::S3::BucketPolicy
      Properties:
        Bucket:
          Ref: PbaAclTestBucket
        PolicyDocument:
          Version: "2012-10-17"
          Statement:
            - Effect: Allow
              Action: s3:GetObject
              Resource:
                Fn::Sub: ${PbaAclTestBucket.Arn}/*
              Principal: "*"

発生したエラー

このままデプロイすると以下のエラーが発生します。

Error:
CREATE_FAILED: PbaAclTestBucketPolicy (AWS::S3::BucketPolicy)
API: s3:PutBucketPolicy Access Denied

4月以降自動的にBlock public accessが有効になることはわかってたのですが、バケットポリシーの作成にも影響があることが抜けていました。
そのため、このエラーを見た時にすぐには原因が分からずだいぶはまってしまいました。
エラーの内容もs3:PutBucketPolicy Access Deniedなのでデプロイを実行のためにassumeroleしている私のロールのIAMポリシーに不足が有るのかと思い右往左往しました。

エラー内容でググるとBlock public accessの設定にパブリックなアクセスが可能になるバケットポリシーの作成をブロックをしない設定を追加する必要があることが分かりました。

serverless.ymlの修正

この設定を盛り込んだserverless.ymlは以下のようになりました。

serverless.yml

resources:
  Resources:
    PbaAclTestBucket:
        Type: AWS::S3::Bucket
        Properties:
          BucketName: pba-acl-test-bucket
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        IgnorePublicAcls: true
        BlockPublicPolicy: false <-- この設定をfalseにする
        RestrictPublicBuckets: true

    PbaAclTestBucketPolicy:
      Type: AWS::S3::BucketPolicy
      Properties:s
        Bucket:
          Ref: PbaAclTestBucket
        PolicyDocument:
          Version: "2012-10-17"
          Statement:
            - Effect: Allow
              Action: s3:GetObject
              Resource:
                Fn::Sub: ${PbaAclTestBucket.Arn}/*
              Principal: "*"

この設定後、デプロイが可能となりました。

その他

BlockPublicPolicyがtrueの場合は意図しないパブリックアクセス可能なポリシーの追加を防いでくれます。 前項でバケットに追加したものと同じポリシーをコンソールから追加してみますと以下の画像のようなメッセージが出て追加をできません。

PublicAccessBlockConfigurationのその他の設定

今回の対処の中でBlock public accessの設定項目の PublicAccessBlockConfigurationについて調べましたので、その他の以下3つのプロパティについても解説致します。

  • BlockPublicAcls
  • IgnorePublicAcls
  • RestrictPublicBuckets

公式のドキュメントの説明は以下のリンク先となります。

BlockPublicAcls

これをtrueに設定すると、パブリックACL(public-read等々)を付けたオブジェクトのPut Objectができなくなります。

IgnorePublicAcls

これをtrueに設定すると、バケット及びオブジェクトの パブリックACLの効果を無視してくれます。パブリックACL付きのオブジェクトをPut Objectはできますが、パブリックACLの機能が効かなくなります。

RestrictPublicBuckets

RestrictPublicBucketsfalseにすると以下のようにバケットが公開状態となります。

バケットのオブジェクトには以下のような形式のURLで普通にアクセスできる状態となります。

https://pba-acl-test-bucket.s3.ap-northeast-1.amazonaws.com/test.json

このような状態は要件によっては許可されない場合が多いと思います。その場合はRestrictPublicBucketstrueにします。

以上。