Problem
I have some old buckets I have setup with AWS SAM/CloudFormation using AccessControl: Private
. This attribute has been deprecated and I’m assuming it will be removed in the future, but I cannot figure out how to remove the attribute and successfully deploy.
When building with the property I now get the following warning:
W3045 Consider using AWS::S3::BucketPolicy instead of AccessControl
This is 100% understandable and expected now as this has officially been marked a legacy property in the AWS documentation.
If I remove the property and try to re-deploy I get the following error:
Resource handler returned message: "The bucket does not allow ACLs (Service: S3, Status Code: 400..."
The bucket is setup with defaults, which means Block all public access
is On
and ACL management is off. I have no idea what CloudFormation is doing to try and configure ACLs on the bucket, but I am assuming if the bucket was set to Private and now you remove the setting, it should just revert to the default… which is Private.
From the documentation:
S3 buckets are created with ACLs disabled by default. Therefore, unless you explicitly set the AWS::S3::OwnershipControls property to enable ACLs, your resource will fail to deploy with any value other than Private. Use cases requiring ACLs are uncommon.
So, the real question I have is, how do I remove the AccessControl property, which as set to the default and should have no effect on the bucket if removed.
Simple Test
T001_test/template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Test for AccessControl Removal
#################################
# Parameters
#################################
Parameters:
BucketName:
Description: S3 Bucket Name
Type: String
Default: so-test-access-control-bucket
#################################
# Resources
#################################
Resources:
S3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Ref BucketName
AccessControl: Private
# A few extra settings just for fun...
LifecycleConfiguration:
Rules:
- Id: "Delete old versions"
Status: Enabled
NoncurrentVersionExpirationInDays: 7
- Id: "Delete all objects older than 120 days"
Status: Enabled
ExpirationInDays: 120
NotificationConfiguration:
EventBridgeConfiguration:
EventBridgeEnabled: true
T001_test/samconfig.toml
# More information about the configuration file can be found here:
# https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html
version = 0.1
[default]
[default.global.parameters]
stack_name = "T001-TEST"
[default.build.parameters]
cached = true
parallel = true
[default.validate.parameters]
lint = true
[default.deploy.parameters]
confirm_changeset = true
image_repositories = []
s3_prefix = "T001-TEST"
region = "us-east-1"
resolve_s3 = true
tags = "AppManagerCFNStackKey=T001-TEST"
[default.package.parameters]
region = "us-east-1"
resolve_s3 = true
[default.sync.parameters]
watch = true
[default.local_start_api.parameters]
warm_containers = "EAGER"
[default.local_start_lambda.parameters]
warm_containers = "EAGER"
Run the following:
sam build
You will get the warnings about the AccessControl property, but you can ignore them.
Deploy with:
sam deploy
The template will successfully deploy (you may need to change the bucket name).
Remove the AccessControl Property
Next, remove the access control property and then build
and deploy
again.
You should get an error just like the following:
I had a similar question about how to make buckets public in the past, but I would prefer NOT to have to add all the PublicAccessBlockConfiguration settings and ownership configuration settings to all of my buckets. I would prefer to simplify and just get back to the defaults.
AWS Came back with a response that worked!
Thank you for providing a working sample template and stack ARN. I was able to reproduce the error message, and also able to successfully remove the AccessControl property without deleting the bucket.
Here are the steps I followed:
- Deploy bucket with AccessControl: Private successfully
- Comment out AccessControl and deploy, this fails to update and rolls back
- Add OwnershipControls, BucketOwnerPreferred, deploys successfully
- Comment out AccessControl and deploy, deploys successfully
- Set ObjectOwnership to BucketOwnerEnforced, deploys successfully
The core of the issue is that bucket ownership settings [1] are strongly tried to the use of ACLs. The default is Bucket owner enforced, which prevents the modifying of ACLs. Removing ACLs is a form of modification which leads us to this issue.
The way forward is to push a stack update that sets bucket ownership controls to BucketOwnerPreferred (allow ALCs), then disable ACLs, then set BucketOwnerEnforced (same as before).