terraform-aws-s3-bucket icon indicating copy to clipboard operation
terraform-aws-s3-bucket copied to clipboard

error creating S3 bucket ACL for: AccessDenied: Access Denied

Open Clasyc opened this issue 1 year ago β€’ 20 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.

Clasyc avatar Jun 30 '23 07:06 Clasyc

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 avatar Jul 20 '23 08:07 yyarmoshyk

@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

5t33 avatar Jul 27 '23 23:07 5t33

my mistake, the error in that case is

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

5t33 avatar Jul 27 '23 23:07 5t33

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.

yyarmoshyk avatar Jul 28 '23 06:07 yyarmoshyk

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

github-actions[bot] avatar Aug 28 '23 00:08 github-actions[bot]

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 avatar Aug 28 '23 08:08 yyarmoshyk

@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.

danijelmarsic2 avatar Sep 11 '23 15:09 danijelmarsic2

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                     = null  # Private bucket
block_public_acls       = true
block_public_policy     = true
ignore_public_acls      = true
restrict_public_buckets = true

Probable cause

I think the probable partial cause of this is related to https://github.com/terraform-aws-modules/terraform-aws-s3-bucket/blob/7263d096e3386493dc5113ad61ad0670e6c99028/main.tf#L80-L81 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.

goetzc avatar Sep 15 '23 17:09 goetzc

I am having the same issue,

: AccessControlListNotSupported: The bucket does not allow ACLs

how to solve it using this module?

kristijorgji avatar Sep 25 '23 13:09 kristijorgji

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 avatar Sep 25 '23 13:09 danijelmarsic2

@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.

kristijorgji avatar Sep 25 '23 17:09 kristijorgji

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.

gerricchaplin avatar Sep 29 '23 11:09 gerricchaplin

I solved the issue by adding these 2 parameters

  control_object_ownership = true
  object_ownership         = "ObjectWriter"

kristijorgji avatar Sep 29 '23 12:09 kristijorgji

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
    }
  ]
}

fabianomartinsrj avatar Oct 04 '23 11:10 fabianomartinsrj

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

github-actions[bot] avatar Nov 04 '23 00:11 github-actions[bot]

As stated before, it seems the cause of this issue is related to: https://github.com/terraform-aws-modules/terraform-aws-s3-bucket/blob/7263d096e3386493dc5113ad61ad0670e6c99028/main.tf#L80-L81 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.

goetzc avatar Nov 04 '23 15:11 goetzc

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

github-actions[bot] avatar Dec 06 '23 00:12 github-actions[bot]

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.

goetzc avatar Dec 07 '23 18:12 goetzc

Should the default resource definition in the readme be changed to this?

# Private bucket with versioning enabled

module "s3_bucket" {
  source = "terraform-aws-modules/s3-bucket/aws"

  bucket = "my-s3-bucket"

  versioning = {
    enabled = true
  }
}

To quote the AWS docs:

A majority of modern use cases in Amazon S3 no longer require the use of ACLs. We recommend that you keep ACLs disabled, except in unusual circumstances where you need to control access for each object individually.

ga-tb avatar Jan 03 '24 15:01 ga-tb

We are getting this access denied error due to the fact that we can not have -

  1. Block public access (bucket settings) Block all public access = true
  2. Access control list (ACL) Everyone (public access) = true

imVipul3000 avatar Feb 11 '24 08:02 imVipul3000

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

github-actions[bot] avatar Mar 13 '24 00:03 github-actions[bot]

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

no.

goetzc avatar Mar 13 '24 00:03 goetzc

I'm also having the same problem when using this module trying to create a bucket with an open-wide policy. I already tried both workarounds proposed:

  • https://github.com/terraform-aws-modules/terraform-aws-s3-bucket/issues/242#issuecomment-1740777305
  • https://github.com/terraform-aws-modules/terraform-aws-s3-bucket/issues/242#issuecomment-1746713560

But none of them work, I keep getting a

β”‚ Error: putting S3 Bucket (***) Policy: operation error S3: PutBucketPolicy, https response error StatusCode: 403, RequestID: ***, HostID: ***, api error AccessDenied: Access Denied

I can create the bucket manually from the console without problems.

bebosudo avatar Mar 28 '24 14:03 bebosudo

Having the same issue.

resource "aws_s3_bucket" "admin_site" {
  bucket = "admin-site"
}
  
resource "aws_s3_bucket_website_configuration" "admin_site" {
  bucket = aws_s3_bucket.admin_site.id

  index_document {
    suffix = "index.html"
  }

  error_document {
    key = "error.html"
  }
}

resource "aws_s3_bucket_acl" "admin_site_acl" {
  bucket = aws_s3_bucket.admin_site.id

  acl = "public-read"
}

resource "aws_s3_bucket_policy" "admin_site_bucket_policy" {
  bucket = aws_s3_bucket.admin_site.id

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action    = ["s3:GetObject"]
        Effect    = "Allow"
        Resource  = "${aws_s3_bucket.admin_site.arn}/*"
        Principal = "*"
      },
    ]
  })
}

The bucket gets created, but both aws_s3_bucket_acl and aws_s3_bucket_policy fail:

β•·
β”‚ Error: creating S3 Bucket (admin-site) ACL: operation error S3: PutBucketAcl, https response error StatusCode: 403, RequestID: EVM82SXRDKB33KAY, HostID: p+rjcfrOZJdO69M0jlUZj4TcNDc7yUQIqxdwNpGX/BGwMM0fsyVwmfY2yv6Im98MCHCuggxpPi4=, api error AccessDenied: Access Denied
β”‚
β”‚   with module.aws.aws_s3_bucket_acl.admin_site_acl,
β”‚   on aws\s3.tf line 17, in resource "aws_s3_bucket_acl" "admin_site_acl":
β”‚   17: resource "aws_s3_bucket_acl" "admin_site_acl" {
β”‚
β•΅
β•·
β”‚ Error: putting S3 Bucket (admin-site) Policy: operation error S3: PutBucketPolicy, https response error StatusCode: 403, RequestID: EVM34M8Z080726JM, HostID: yvZGvcPo989o84vqdkyvTsVY6SHS30HmCGjqEos0zmKbaWWfr+LN2xgLeFoFYhPbKrfWJDgMBsM=, api error AccessDenied: Access Denied
β”‚
β”‚   with module.aws.aws_s3_bucket_policy.admin_site_bucket_policy,
β”‚   on aws\s3.tf line 23, in resource "aws_s3_bucket_policy" "admin_site_bucket_policy":
β”‚   23: resource "aws_s3_bucket_policy" "admin_site_bucket_policy" {
β”‚
β•΅

nibblesnbits avatar Apr 01 '24 02:04 nibblesnbits

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

https://github.com/terraform-aws-modules/terraform-aws-s3-bucket/blob/7263d096e3386493dc5113ad61ad0670e6c99028/main.tf#L80-L81

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.

that combination of flags just does not make sense, this code below works:

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

eugenetaranov avatar Apr 18 '24 15:04 eugenetaranov

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

github-actions[bot] avatar May 19 '24 00:05 github-actions[bot]

This issue was automatically closed because of stale in 10 days

github-actions[bot] avatar May 30 '24 00:05 github-actions[bot]

Lots of action and still gets closed..?

ElvenSpellmaker avatar May 30 '24 00:05 ElvenSpellmaker

Lots of action and still gets closed..?

And as "not planned."

Thankfully, my crappy workaround of manually creating the bucket works, but yeah... 🀦

nibblesnbits avatar May 30 '24 00:05 nibblesnbits

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

github-actions[bot] avatar Jun 29 '24 02:06 github-actions[bot]