- Notifications
You must be signed in to change notification settings - Fork 9.8k
Description
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.
Relevant resources:
aws_s3_bucketaws_s3_bucket_aclaws_s3_bucket_ownership_controlsaws_s3_bucket_public_access_block
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:
- Inline
aclwhere the value is notprivate. - Standalone
aws_s3_bucket_aclresource 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.