Skip to content

Notice: S3 - Changes to Defaults (Block Public Access and ACL's) #28353

@ewbankkit

Description

@ewbankkit

Starting in April 2023, Amazon S3 will introduce two new default bucket security settings by automatically enabling S3 Block Public Access and disabling S3 access control lists (ACLs) for all new S3 buckets.

Announcement
Blog post
FAQ

Relevant resources:

  • aws_s3_bucket
  • aws_s3_bucket_acl
  • aws_s3_bucket_ownership_controls
  • aws_s3_bucket_public_access_block

Relates #22069
Relates #6607


Terraform AWS Provider Impact

This section will detail the impact of the upcoming AWS S3 security changes on the Terraform AWS Provider.

Summary

The impending S3 security changes will not require breaking changes to v3 or v4 of the Terraform AWS provider. However, some previously valid S3 bucket ACL configurations will begin returning errors for net-new buckets. Existing buckets (and their corresponding terraform configuration) are not impacted.

ACL Changes

ACLs can be defined either directly on the aws_s3_bucket resource, or via the standalone aws_s3_bucket_acl resource. This is true in both v3 and v4 or the provider, though the acl attribute on the S3 bucket resource was officially deprecated in v4.

Inline:

resource "aws_s3_bucket" "example" { bucket = "my-tf-test-bucket" acl = "private" }

Standalone Resource:

resource "aws_s3_bucket" "example" { bucket = "my-tf-test-bucket" } resource "aws_s3_bucket_acl" "example" { bucket = aws_s3_bucket.example.id acl = "private" }

While existing buckets are not impacted by the impending security changes, the following configuration patterns are impacted for net-new buckets:

  1. Inline acl where the value is not private.
  2. Standalone aws_s3_bucket_acl resource with default security settings.

Inline acl where the value is not private

In both v3 and v4 of the provider, the inline acl attribute defaults to private when unset. Passing a value of private on bucket creation continues to work post-security changes, but any other value requires the default object ownership settings be changed in the same request. Currently, there is no way to do this via the aws_s3_bucket resource. Adoption of the standalone aws_s3_bucket_acl resource, paired with the aws_s3_bucket_public_access_block and aws_s3_bucket_ownership_controls resources allows the default security settings to be adjusted as necessary.

Existing Configuration

resource "aws_s3_bucket" "example" { bucket = "my-tf-test-bucket" acl = "public-read" }

Error

Error: creating Amazon S3 (Simple Storage) Bucket (my-bucket): InvalidBucketAclWithObjectOwnership: Bucket cannot have ACLs set with ObjectOwnership's BucketOwnerEnforced setting

Alternative Configuration

This configuration splits bucket and ACL creation into separate API calls, with the requisite block public access and object ownership API calls in between.

resource "aws_s3_bucket" "example" { bucket = "my-tf-test-bucket" } resource "aws_s3_bucket_public_access_block" "example" { bucket = aws_s3_bucket.example.id block_public_acls = false block_public_policy = false ignore_public_acls = false restrict_public_buckets = false } resource "aws_s3_bucket_ownership_controls" "example" { bucket = aws_s3_bucket.example.id rule { object_ownership = "BucketOwnerPreferred" } } resource "aws_s3_bucket_acl" "example" { depends_on = [ aws_s3_bucket_public_access_block.example, aws_s3_bucket_ownership_controls.example, ] bucket = aws_s3_bucket.example.id acl = "public-read" }

Standalone aws_s3_bucket_acl resource with default security settings

With the default security settings unchanged, any attempt to set an ACL on an existing bucket via the standalone ACL resource will fail, even if the value is private.

Existing Configuration

resource "aws_s3_bucket" "example" { bucket = "my-tf-test-bucket" } resource "aws_s3_bucket_acl" "example" { bucket = aws_s3_bucket.example.id acl = "private" }

Error

Error: error creating S3 bucket ACL for my-bucket: AccessControlListNotSupported: The bucket does not allow ACLs

Alternative Configuration

With the new default security settings, a private ACL definition can likely be removed completely as the default security settings already ensure public access is restricted upon bucket creation.

However, if a private ACL is explicitly required, the following configuration splits bucket and ACL creation into separate API calls, with the requisite object ownership API call in between.

resource "aws_s3_bucket" "example" { bucket = "my-tf-test-bucket" } resource "aws_s3_bucket_ownership_controls" "example" { bucket = aws_s3_bucket.example.id rule { object_ownership = "BucketOwnerPreferred" } } resource "aws_s3_bucket_acl" "example" { depends_on = [aws_s3_bucket_ownership_controls.example] bucket = aws_s3_bucket.example.id acl = "private" }

For use cases requiring non-private ACLs, an additional aws_s3_bucket_public_access_block resource would also be required, as documented in the inline use case above.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementRequests to existing resources that expand the functionality or scope.service/s3Issues and PRs that pertain to the s3 service.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions