Contents

Expected changes in S3 ACL behavior with Terraform

Contents

At the end of April, AWS made changes to the default settings for S3 buckets. Newly created buckets have the ACL mechanism deactivated by default. This may cause errors for Terraform users who have not explicitly enabled ACLs on their buckets, or are configuring the buckets in the “old way”.

Example error message:

aws_s3_bucket_acl.thanos_data: Creating...
╷
│ Error: error creating S3 bucket ACL for sample-bucket: AccessControlListNotSupported: The bucket does not allow ACLs
│       status code: 400, request id: ZXXXXXXXXXXXXXXH, host id: sXXX+XXX==
│
│   with aws_s3_bucket_acl.thanos_data,
│   on s3.tf line 7, in resource "aws_s3_bucket_acl" "thanos_data":
│    7: resource "aws_s3_bucket_acl" "thanos_data" {

There are two ways to deal with this:

  • explicitly enable the ACLs on the buckets
  • resign from aws_s3_bucket_acl resource and use aws_s3_bucket_public_access_block instead

ACLs are deprecated and have been replaced by IAM policies. Except some edge cases, you should be able to use IAM policies instead of ACLs.

Example IaC code change:

-resource "aws_s3_bucket_acl" "config" {
-  bucket = aws_s3_bucket.config.id
-  acl    = "private"
-}
+resource "aws_s3_bucket_public_access_block" "config" {
+  bucket                  = aws_s3_bucket.config.bucket
+  block_public_acls       = true
+  block_public_policy     = true
+  ignore_public_acls      = true
+  restrict_public_buckets = true
+}

Terraform plan of the change above:

 # prometheus[0].aws_s3_bucket_acl.config will be destroyed
  # (because aws_s3_bucket_acl.config is not in configuration)
  - resource "aws_s3_bucket_acl" "config" {
      - acl    = "private" -> null
      - bucket = "sample-bucket" -> null
      - id     = "sample-bucket,private" -> null
 
      - access_control_policy {
          - grant {
              - permission = "FULL_CONTROL" -> null
 
              - grantee {
                  - id   = "XXX" -> null
                  - type = "CanonicalUser" -> null
                }
            }
          - owner {
              - id = "XXX" -> null
            }
        }
    }
 
  # prometheus[0].aws_s3_bucket_public_access_block.config will be created
  + resource "aws_s3_bucket_public_access_block" "config" {
      + block_public_acls       = true
      + block_public_policy     = true
      + bucket                  = "sample-bucket"
      + id                      = (known after apply)
      + ignore_public_acls      = true
      + restrict_public_buckets = true
    }
 
Plan: 1 to add, 0 to change, 1 to destroy.