terraform-aws-modules / terraform-aws-s3-bucket

Terraform module to create AWS S3 resources 🇺🇦

Home Page:https://registry.terraform.io/modules/terraform-aws-modules/s3-bucket/aws

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

error creating S3 bucket ACL for: AccessDenied: Access Denied

Clasyc opened this issue · comments

Description

If I try to create public-read bucket I get this error:

│ Error: error creating S3 bucket ACL for XXX: AccessDenied: Access Denied
│       status code: 403, request id: NPTTE3W6DYEYEVKF, host id: XXX
│ 
│   with module.s3_public_buckets.aws_s3_bucket_acl.this[0],
│   on .terraform/modules/s3_public_buckets/main.tf line 41, in resource "aws_s3_bucket_acl" "this":
│   41: resource "aws_s3_bucket_acl" "this" {

Versions

  • Module version [Required]:

  • Terraform version: v1.5.1

  • Provider version(s):
    provider registry.terraform.io/hashicorp/aws v4.67.0

Reproduction Code [Required]

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }
}
provider "aws" {
  region  = "eu-west-1"
  profile = "default"
}

module "s3_public_buckets" {
  version = "3.14.0"
  source = "terraform-aws-modules/s3-bucket/aws"
  bucket = "XXX"

  acl    = "public-read"

  control_object_ownership = true
  object_ownership         = "ObjectWriter"

  versioning = {
    enabled = false
  }

  cors_rule = [
    {
      allowed_headers = ["*"]
      allowed_methods = ["PUT", "POST", "GET", "DELETE"]
      allowed_origins = ["*"]
      max_age_seconds = 3000
    }
  ]
}

Expected behavior

I see successfully created public-read bucket.

Actual behavior

Receiving Error: error creating S3 bucket ACL for XXX: AccessDenied: Access Denied error.

The reported problem looks more like your default IAM user doesn't have sufficient permissions required to create the bucket.
Possible debuging options are the following:

  1. Check Cloudtrail event that represents the bucket create operation.
  2. Increase terraform verbosity by setting the environment variable export TF_LOG= DEBUG
  3. Use IAMLive to detect the missing IAM policy statements

I'd recommend to use first 2 suggestions and share the output here

@yyarmoshyk I'm not sure that's the case. AWS recently changed how ACLs work.
https://aws.amazon.com/about-aws/whats-new/2022/12/amazon-s3-automatically-enable-block-public-access-disable-access-control-lists-buckets-april-2023/

https://docs.aws.amazon.com/AmazonS3/latest/userguide/acl-overview.html

If your bucket uses the bucket owner enforced setting for S3 Object Ownership, you must use policies to grant access to your bucket and the objects in it. With the bucket owner enforced setting enabled, requests to set access control lists (ACLs) or update ACLs fail and return the AccessControlListNotSupported error code. Requests to read ACLs are still supported.

I'm attempting to apply a public read ACL to a bucket with full admin and it's giving me 403s

my mistake, the error in that case is

putting S3 object ACL: AccessControlListNotSupported: The bucket does not allow ACLs

I was able to reproduce it. And the problem is really strange.

The code of the module is up to date with the latest requirements but for some reason the terraform plan still shows all the parameters when creating the bucket:

  # module.s3_public_buckets.aws_s3_bucket.this[0] will be created
  + resource "aws_s3_bucket" "this" {
      + acceleration_status         = (known after apply)
      + acl                         = (known after apply)
      + arn                         = (known after apply)
      + bucket                      = (known after apply)
      + bucket_domain_name          = (known after apply)
      + bucket_prefix               = "yyarmoshyk-test-bucket"
      + bucket_regional_domain_name = (known after apply)
      + force_destroy               = false
      + hosted_zone_id              = (known after apply)
      + id                          = (known after apply)
      + object_lock_enabled         = false
      + policy                      = (known after apply)
      + region                      = (known after apply)
      + request_payer               = (known after apply)
      + tags_all                    = (known after apply)
      + website_domain              = (known after apply)
      + website_endpoint            = (known after apply)
    }

Even with the latest aws provider version, latest terraform and latest terraform-aws-s3-bucket module REF.

This issue has been automatically marked as stale because it has been open 30 days
with no activity. Remove stale label or comment or this issue will be closed in 10 days

Iamlive stops at the following message

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "sts:GetCallerIdentity",
        "s3:CreateBucket"
      ],
      "Resource": "*"
    }
  ]
}

It fails with terraform v1.5.4 and AWS provider v5.10.0. According to the CloudTrail the x-amz-acl is included into the requestParameters of the CreateBucket command.

The same problem appears with terraform v0.13.5 and aws provider v4.67.0

It should no appear but it does. I'll post here if I find what is wrong with it. It is very strange that this problem is not reported by more people.

@yyarmoshyk I was getting the following error:

│ Error: creating S3 bucket ACL for s3_bucket_test_acl_error: AccessControlListNotSupported: The bucket does not allow ACLs │ status code: 400, request id: WXQ14Z20NM62WYBY, host id: 8W4OuR7Y9NAGvqArXoPFkvEx8LM/dgCbf7Iya9xYuESNEv3u0deBkS/VG5eRgwS8hSTYtnOQCSk= │ │ with module.s3_bucket_test_acl_error.aws_s3_bucket_acl.this[0], │ on .terraform/modules/s3_bucket_test_acl_error/main.tf line 45, in resource "aws_s3_bucket_acl" "this": │ 45: resource "aws_s3_bucket_acl" "this" {
I have just removed the parameter acl from my terraform configuration. Now, the acl parameter gets the "null" value by default and this prevents the resource "aws_s3_bucket_acl" in line 45 of the source code: https://github.com/terraform-aws-modules/terraform-aws-s3-bucket/blob/master/main.tf#L45

`
module "s3_bucket_test_acl_error" {
source = "terraform-aws-modules/s3-bucket/aws"
version = "3.15.1"

this paramter was removed => acl = "private"
bucket_prefix = "s3_bucket_test_acl_error-dev-"
expected_bucket_owner = local.account_id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true

cors_rule = [
{
allowed_methods = ["PUT", "POST", "GET"]
allowed_origins = [""]
allowed_headers = ["
"]
max_age_seconds = 3000
}
]
}
`
As stated in a link provided by @5t33, AWS does not allow us to create ACLs anymore and commenting out the acl parameter prevents the resource "aws_s3_bucket_acl" to be created and thus the error AccessControlListNotSupported is being avoided.

I get the same error creating a new bucket with a new TF setup (no state).

Interesting enough, there is a workaround: when manually changing the bucket "Object Ownership" settings, from "ACL disabled" (which is BucketOwnerEnforced) to "ACL enabled" (which is BucketOwnerPreferred), then Terraform is able to apply the settings successfully:

image

The Terraform code that fails is:

acl                     = "private"
block_public_acls       = true
block_public_policy     = true
restrict_public_buckets = true
ignore_public_acls      = true
object_ownership        = "BucketOwnerEnforced"

Probable cause

I think the probable partial cause of this is related to

# This `depends_on` is to prevent "AccessControlListNotSupported: The bucket does not allow ACLs."
depends_on = [aws_s3_bucket_ownership_controls.this]
which expects aws_s3_bucket_ownership_controls.this to exist, but it does not always exist, as it depends on var.control_object_ownership being true, but this is false by default.

Workaround

Thus, setting control_object_ownership = true is another workaround this bug.

I am having the same issue,

: AccessControlListNotSupported: The bucket does not allow ACLs

how to solve it using this module?

I am having the same issue,

: AccessControlListNotSupported: The bucket does not allow ACLs

how to solve it using this module?

I have just removed the parameter acl = "private" from my configuration and the problem disappeared.

@danijelmarsic2 Thanks for the reply but thatt is not a proper solution.

I need acl and also policy = { in my s3 bucket, the proper solution would be to know how to use this module to achieve it.

Also take time to check your default settings as you may be blocked at the top level. On the page "Block Public Access settings for this account" you can turn this on or off. You will not be able to override these per bucket depending on your settings.

I solved the issue by adding these 2 parameters

  control_object_ownership = true
  object_ownership         = "ObjectWriter"

Based on the provider docs, for public-read, we must set bucket_ownership_controls and bucket_public_access_block. Using the module, would something like:

data "aws_caller_identity" "current" {}

module "my_public_S3_bucket" {
  source  = "terraform-aws-modules/s3-bucket/aws"
  version = "3.15.1"

  bucket = "my-public-s3-bucket"

  block_public_acls       = false
  block_public_policy     = false
  ignore_public_acls      = false
  restrict_public_buckets = false

  control_object_ownership = true
  object_ownership         = "BucketOwnerPreferred"
  expected_bucket_owner    = data.aws_caller_identity.current.account_id
  acl                      = "public-read"

  attach_policy = true
  policy = file("./my-bucket-policy.json")

  cors_rule = [
    {
      allowed_headers = ["*"]
      allowed_methods = ["GET"]
      allowed_origins = ["https://my-app.domain.com"]
      max_age_seconds = 3000
    }
  ]
}

This issue has been automatically marked as stale because it has been open 30 days
with no activity. Remove stale label or comment or this issue will be closed in 10 days

As stated before, it seems the cause of this issue is related to:

# This `depends_on` is to prevent "AccessControlListNotSupported: The bucket does not allow ACLs."
depends_on = [aws_s3_bucket_ownership_controls.this]
which expects aws_s3_bucket_ownership_controls.this to exist, but it does not always exist, as it depends on var.control_object_ownership being true, but this is false by default.

This issue has been automatically marked as stale because it has been open 30 days
with no activity. Remove stale label or comment or this issue will be closed in 10 days

This issue has been automatically marked as stale because it has been open 30 days with no activity. Remove stale label or comment or this issue will be closed in 10 days

Hmm, still a reproducible issue.