How to create public S3 bucket in Serverless

32 Views Asked by At

I have the following Servlerless config that is trying to create a public access S3 bucket that I can use for hosting images for a website. I want to make sure that it has GetObject access to anybody since they will be public images.

provider:
  name: aws
  runtime: nodejs18.x
  timeout: 25
  iam:
    role:
      statements:
        - Effect: Allow
          Action:
            - 's3:GetObject'
            - 's3:PutBucketPolicy'
          Resource:
            - 'arn:aws:s3:::my-bucket-name/*'


resources:
  Resources:

    WebImagesBucket:
      Type: AWS::S3::Bucket
      Properties:
        BucketName: my-bucket-name
        # AccessControl: PublicRead
        # PublicAccessBlockConfiguration:
        #   BlockPublicAcls: false
        #   BlockPublicPolicy: false
        #   IgnorePublicAcls: false
        #   RestrictPublicBuckets: false

    PublicReadGetObject:
      Type: AWS::S3::BucketPolicy
      Properties: 
        Bucket:
          Ref: "WebImagesBucket"
        PolicyDocument:
          Statement:
            - Effect: Allow
              Sid: PublicReadGetObject
              Action:
                - 's3:GetObject'
              Resource:
                - 'arn:aws:s3:::my-bucket-name/*'
              Principal: "*"

I am creating the S3 bucket resource but creating the PublicReadGetObject policy fails with a 403:

CREATE_FAILED: PublicReadGetObject (AWS::S3::BucketPolicy)
Resource handler returned message: "Access Denied (Service: S3, Status Code: 403

Do I need to update the provider iam to have some other policy actions?

I tried using AccessControl but seems like that has been deprecated in favour of policy.

Any help on getting this working would be greatly appreciated. Thanks

1

There are 1 best solutions below

4
jarmod On BEST ANSWER

This is probably related to account-level or default bucket-level Block Public Access. See Configuring Block Public Access. You will need to disable BPA if you want to put a bucket policy that allows public access.

Also, note that s3:PutBucketPolicy is a bucket-level action, not object-level, so the ARN arn:aws:s3:::my-bucket-name/* is incorrect. It needs to be arn:aws:s3:::my-bucket-name, for example:

provider:
  name: aws
  runtime: nodejs18.x
  timeout: 25
  iam:
    role:
      statements:
        - Effect: Allow
          Action:
            - 's3:GetObject'
          Resource:
            - 'arn:aws:s3:::my-bucket-name/*'
        - Effect: Allow
          Action:
            - 's3:PutBucketPolicy'
          Resource:
            - 'arn:aws:s3:::my-bucket-name'