I am having issues creating public buckets as AWS SAM recently deprecated the use of:
AccessControl: PublicRead
on AWS S3 Bucket resources.
Example template:
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
public-bucket-issues
################################
# Parameters
################################
Parameters:
BucketName:
Description: S3 bucket name
Type: String
Default: 'my-test-public-bucket-abc123'
################################
# Resources
################################
Resources:
PublicBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Ref BucketName
# Set up for public website hosting
AccessControl: PublicRead
WebsiteConfiguration:
IndexDocument: index.html
ErrorDocument: index.html
CorsConfiguration:
CorsRules:
- AllowedOrigins:
- "*"
- !Ref BucketName
AllowedMethods:
- GET
- POST
- PUT
- DELETE
- HEAD
AllowedHeaders:
- "*"
MaxAge: 3000
OwnershipControls:
Rules:
- ObjectOwnership: BucketOwnerPreferred
This configuration works when you deploy it, but I get the following linting errors (breaking all CICD):
W3045 Consider using AWS::S3::BucketPolicy instead of AccessControl
/path/to/template.yaml:27:7
Error: Linting failed. At least one linting rule was matched to the provided template.
As you can see from the Cloud Formation documentation, this is indeed deprecated:
The SAM Linter is so kind to give me a hint that I should use a bucket policy! So I add the bucket policy to my bucket as follows:
PublicBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref PublicBucket
PolicyDocument:
Version: "2012-10-17"
Statement:
- Sid: PublicReadGetObject
Effect: Allow
Principal: "*"
Action: "s3:GetObject"
Resource: !Sub "arn:aws:s3:::${BucketName}/*"
This gives me a permissions error when I deploy when it tries to create the policy (even through I am an administrator on the account with no explicit DENYs on any user policies):
CREATE_FAILED AWS::S3::BucketPolicy PublicBucketPolicy Resource handler returned message: "Access
Denied (Service: S3, Status Code: 403, Request... HandlerErrorCode: AccessDenied)
So, CloudFormation has deprecated the AccessControl
attribute on the S3 bucket, but not given us clear instructions on how to properly setup a public bucket. They point to a guide that talks about how ACLs work, but not how to enable them on a bucket via CloudFormation. Any help on how I can set this up would be very helpful. I would like to be able to setup public website hosting via cloudfront but am having issues setting up a policy as directed!
You need to specify the Public Access configuration of your bucket (AWS doc). I had the same issue on terraform until I did that.
According to the doc, it should look like this:
Resources:
Bucket:
Type: AWS::S3::Bucket
Properties:
PublicAccessBlockConfiguration:
BlockPublicAcls : true
BlockPublicPolicy : false # Will allow the creation of the policy
IgnorePublicAcls : true
RestrictPublicBuckets : false # Will allow non-AWS entities to read what is inside the bucket
Also, here the terraform version of this for reference:
resource "aws_s3_bucket_public_access_block" "public_image_bucket_access" {
bucket = aws_s3_bucket.public_image_bucket.id
block_public_acls = true
ignore_public_acls = true
}
Hope this helps