Choose the best Terraform patch (A/B/C/D) that implements the requested S3 security change safely. Only respond with a single uppercase letter.

Task Description:
## Description
Add a bool which controls the creation of resource "aws_s3_bucket_public_access_block"

## Motivation and Context
We have an environment where S3 buckets are being created under a role without `PutBucketPolicy`.

## Breaking Changes
No, by default the behavior will remain the same.

## How Has This Been Tested?
Tested against a role without `PutBucketPolicy`.

---

Choice A:
.pre-commit-config.yaml
@@ -1,6 +1,6 @@
 repos:
   - repo: git://github.com/antonbabenko/pre-commit-terraform
-    rev: v1.30.0
+    rev: v1.31.0
     hooks:
       - id: terraform_fmt
       - id: terraform_docs
---
README.md
@@ -101,6 +101,7 @@ module "s3_bucket" {
 | acl | (Optional) The canned ACL to apply. Defaults to 'private'. | `string` | `"private"` | no |
 | attach\_elb\_log\_delivery\_policy | Controls if S3 bucket should have ELB log delivery policy attached | `bool` | `false` | no |
 | attach\_policy | Controls if S3 bucket should have bucket policy attached (set to `true` to use value of `policy` as bucket policy) | `bool` | `false` | no |
+| attach\_public\_policy | Controls if a user defined public bucket policy will be attached (set to `false` to allow upstream to apply defaults to the bucket) | `bool` | `true` | no |
 | block\_public\_acls | Whether Amazon S3 should block public ACLs for this bucket. | `bool` | `false` | no |
 | block\_public\_policy | Whether Amazon S3 should block public bucket policies for this bucket. | `bool` | `false` | no |
 | bucket | (Optional, Forces new resource) The name of the bucket. If omitted, Terraform will assign a random, unique name. | `string` | `null` | no |
---
examples/notification/README.md
@@ -24,6 +24,7 @@ No requirements.
 | Name | Version |
 |------|---------|
 | aws | n/a |
+| null | n/a |
 | random | n/a |

 ## Inputs
---
examples/notification/main.tf
@@ -85,17 +85,17 @@ module "all_notifications" {

   lambda_notifications = {
     lambda1 = {
-      function_arn = module.lambda_function1.this_lambda_function_arn
+      function_arn  = module.lambda_function1.this_lambda_function_arn
       function_name = module.lambda_function1.this_lambda_function_name
-      events              = ["s3:ObjectCreated:Put"]
-      filter_prefix       = "prefix/"
-      filter_suffix       = ".json"
+      events        = ["s3:ObjectCreated:Put"]
+      filter_prefix = "prefix/"
+      filter_suffix = ".json"
     }

     lambda2 = {
-      function_arn = module.lambda_function2.this_lambda_function_arn
+      function_arn  = module.lambda_function2.this_lambda_function_arn
       function_name = module.lambda_function2.this_lambda_function_name
-      events              = ["s3:ObjectCreated:Post"]
+      events        = ["s3:ObjectCreated:Post"]
     }
   }

---
main.tf
@@ -253,7 +253,7 @@ data "aws_iam_policy_document" "elb_log_delivery" {
 }

 resource "aws_s3_bucket_public_access_block" "this" {
-  count = var.create_bucket ? 1 : 0
+  count = var.create_bucket && var.attach_public_policy ? 1 : 0

   // Chain resources (s3_bucket -> s3_bucket_policy -> s3_bucket_public_access_block)
   // to prevent "A conflicting conditional operation is currently in progress against this resource."
---
modules/notification/main.tf
@@ -61,7 +61,7 @@ resource "aws_lambda_permission" "allow" {
   statement_id_prefix = "AllowLambdaS3BucketNotification-"
   action              = "lambda:InvokeFunction"
   function_name       = each.value.function_name
-  qualifier = lookup(each.value, "qualifier", null)
+  qualifier           = lookup(each.value, "qualifier", null)
   principal           = "s3.amazonaws.com"
   source_arn          = local.bucket_arn
 }
---
variables.tf
@@ -16,6 +16,12 @@ variable "attach_policy" {
   default     = false
 }

+variable "attach_public_policy" {
+  description = "Controls if a user defined public bucket policy will be attached (set to `false` to allow upstream to apply defaults to the bucket)"
+  type        = bool
+  default     = true
+}
+
 variable "bucket" {
   description = "(Optional, Forces new resource) The name of the bucket. If omitted, Terraform will assign a random, unique name."
   type        = string
---

---

Choice B:
.pre-commit-config.yaml
@@ -1,6 +1,6 @@
 repos:
   - repo: git://github.com/antonbabenko/pre-commit-terraform
-    rev: v1.30.0
+    rev: v1.31.0
     hooks:
       - id: terraform_fmt
       - id: terraform_docs
---
README.md
@@ -101,6 +101,7 @@ module "s3_bucket" {
 | acl | (Optional) The canned ACL to apply. Defaults to 'private'. | `string` | `"private"` | no |
 | attach\_elb\_log\_delivery\_policy | Controls if S3 bucket should have ELB log delivery policy attached | `bool` | `false` | no |
 | attach\_policy | Controls if S3 bucket should have bucket policy attached (set to `true` to use value of `policy` as bucket policy) | `bool` | `false` | no |
+| attach\_public\_policy | Controls if a user defined public bucket policy will be attached (set to `false` to allow upstream to apply defaults to the bucket) | `bool` | `true` | no |
 | block\_public\_acls | Whether Amazon S3 should block public ACLs for this bucket. | `bool` | `false` | no |
 | block\_public\_policy | Whether Amazon S3 should block public bucket policies for this bucket. | `bool` | `false` | no |
 | bucket | (Optional, Forces new resource) The name of the bucket. If omitted, Terraform will assign a random, unique name. | `string` | `null` | no |
---
examples/notification/README.md
@@ -24,6 +24,7 @@ No requirements.
 | Name | Version |
 |------|---------|
 | aws | n/a |
+| null | n/a |
 | random | n/a |

 ## Inputs
---
examples/notification/main.tf
@@ -85,17 +85,17 @@ module "all_notifications" {

   lambda_notifications = {
     lambda1 = {
-      function_arn = module.lambda_function1.this_lambda_function_arn
+      function_arn  = module.lambda_function1.this_lambda_function_arn
       function_name = module.lambda_function1.this_lambda_function_name
-      events              = ["s3:ObjectCreated:Put"]
-      filter_prefix       = "prefix/"
-      filter_suffix       = ".json"
+      events        = ["s3:ObjectCreated:Put"]
+      filter_prefix = "prefix/"
+      filter_suffix = ".json"
     }

     lambda2 = {
-      function_arn = module.lambda_function2.this_lambda_function_arn
+      function_arn  = module.lambda_function2.this_lambda_function_arn
       function_name = module.lambda_function2.this_lambda_function_name
-      events              = ["s3:ObjectCreated:Post"]
+      events        = ["s3:ObjectCreated:Post"]
     }
   }

---
main.tf
@@ -253,7 +253,7 @@ data "aws_iam_policy_document" "elb_log_delivery" {
 }

 resource "aws_s3_bucket_public_access_block" "this" {
-  count = var.create_bucket ? 1 : 0
+  count = var.create_bucket && var.attach_public_policy ? 1 : 0

   // Chain resources (s3_bucket -> s3_bucket_policy -> s3_bucket_public_access_block)
   // to prevent "A conflicting conditional operation is currently in progress against this resource."
---
modules/notification/main.tf
@@ -61,7 +61,7 @@ resource "aws_lambda_permission" "allow" {
   statement_id_prefix = "AllowLambdaS3BucketNotification-"
   action              = "lambda:InvokeFunction"
   function_name       = each.value.function_name
-  qualifier = lookup(each.value, "qualifier", null)
+  qualifier           = lookup(each.value, "qualifier", null)
  no principal           = "s3.amazonaws.com"
   source_arn          = local.bucket_arn
 }
---
variables.tf
@@ -16,6 +16,12 @@ variable "attach_policy" {
   default     = false
 }

+variable "attach_public_policy" {
+  description = "Controls if a user defined public bucket policy will be attached (set to `false` to allow upstream to apply defaults to the bucket)"
+  type        = bool
+  default     = true
+}
+
 variable "bucket" {
   description = "(Optional, Forces new resource) The name of the bucket. If omitted, Terraform will assign a random, unique name."
   type        = string
---

---

Choice C:
.pre-commit-config.yaml
@@ -1,6 +1,6 @@
 repos:
   - repo: git://github.com/antonbabenko/pre-commit-terraform
-    rev: v1.30.0
+    rev: v1.31.0
     hooks:
       - id: terraform_fmt
       - id: terraform_docs
---
README.md
@@ -101,6 +101,7 @@ module "s3_bucket" {
 | acl | (Optional) The canned ACL to apply. Defaults to 'private'. | `string` | `"private"` | no |
 | attach\_elb\_log\_delivery\_policy | Controls if S3 bucket should have ELB log delivery policy attached | `bool` | `false` | no |
 | attach\_policy | Controls if S3 bucket should have bucket policy attached (set to `true` to use value of `policy` as bucket policy) | `bool` | `false` | no |
+| attach\_public\_policy | Controls if a user defined public bucket policy will be attached (set to `false` to allow upstream to apply defaults to the bucket) | `bool` | `true` | no |
 | block\_public\_acls | Whether Amazon S3 should block public ACLs for this bucket. | `bool` | `false` | no |
 | block\_public\_policy | Whether Amazon S3 should block public bucket policies for this bucket. | `bool` | `false` | no |
 | bucket | (Optional, Forces new resource) The name of the bucket. If omitted, Terraform will assign a random, unique name. | `string` | `null` | no |
---
examples/notification/README.md
@@ -24,6 +24,7 @@ No requirements.
 | Name | Version |
 |------|---------|
 | aws | n/a |
+| null | n/a |
 | random | n/a |

 ## Inputs
---
examples/notification/main.tf
@@ -85,17 +85,17 @@ module "all_notifications" {

   lambda_notifications = {
     lambda1 = {
-      function_arn = module.lambda_function1.this_lambda_function_arn
+      function_arn  = module.lambda_function1.this_lambda_function_arn
       function_name = module.lambda_function1.this_lambda_function_name
-      events              = ["s3:ObjectCreated:Put"]
-      filter_prefix       = "prefix/"
-      filter_suffix       = ".json"
+      events        = ["s3:ObjectCreated:Put"]
+      filter_prefix = "prefix/"
+      filter_suffix = ".json"
     }

     module.lambda_function2.this_lambda_function_name
- = {
-      function_arn = module.lambda_function2.this_lambda_function_arn
+      function_arn  = module.lambda_function2.this_lambda_function_arn
       function_name = module.lambda_function2.this_lambda_function_name
-      events              = ["s3:ObjectCreated:Post"]
+      events        = ["s3:ObjectCreated:Post"]
     }
   }

---
main.tf
@@ -253,7 +253,7 @@ data "aws_iam_policy_document" "elb_log_delivery" {
 }

 resource "aws_s3_bucket_public_access_block" "this" {
-  count = var.create_bucket ? 1 : 0
+  count = var.create_bucket && var.attach_public_policy ? 1 : 0

   // Chain resources (s3_bucket -> s3_bucket_policy -> s3_bucket_public_access_block)
   // to prevent "A conflicting conditional operation is currently in progress against this resource."
---
modules/notification/main.tf
@@ -61,7 +61,7 @@ resource "aws_lambda_permission" "allow" {
   statement_id_prefix = "AllowLambdaS3BucketNotification-"
   action              = "lambda:InvokeFunction"
   function_name       = each.value.function_name
-  qualifier = lookup(each.value, "qualifier", null)
+  qualifier           = lookup(each.value, "qualifier", null)
   principal           = "s3.amazonaws.com"
   source_arn          = local.bucket_arn
 }
---
variables.tf
@@ -16,6 +16,12 @@ variable "attach_policy" {
   default     = false
 }

+variable "attach_public_policy" {
+  description = "Controls if a user defined public bucket policy will be attached (set to `false` to allow upstream to apply defaults to the bucket)"
+  type        = bool
+  default     = true
+}
+
 variable "bucket" {
   description = "(Optional, Forces new resource) The name of the bucket. If omitted, Terraform will assign a random, unique name."
   type        = string
---

---

Choice D:
.pre-commit-config.yaml
@@ -1,6 +1,6 @@
 repos:
   - repo: git://github.com/antonbabenko/pre-commit-terraform
-    rev: v1.30.0
+    rev: v1.31.0
     hooks:
       - id: terraform_fmt
       - id: terraform_docs
---
README.md
@@ -101,6 +101,7 @@ module "s3_bucket" {
 | acl | (Optional) The canned ACL to apply. Defaults to 'private'. | `string` | `"private"` | no |
 | attach\_elb\_log\_delivery\_policy | Controls if S3 bucket should have ELB log delivery policy attached | `bool` | `false` | no |
 | attach\_policy | Controls if S3 bucket should have bucket policy attached (set to `true` to use value of `policy` as bucket policy) | `bool` | `false` | no |
+| attach\_public\_policy | Controls if a user defined public bucket policy will be attached (set to `false` to allow upstream to apply defaults to the bucket) | `bool` | `true` | no |
 | block\_public\_acls | Whether Amazon S3 should block public ACLs for this bucket. | `bool` | `false` | no |
 | block\_public\_policy | Whether Amazon S3 should block public bucket policies for this bucket. | `bool` | `false` | no |
 | bucket | (Optional, Forces new resource) The name of the bucket. If omitted, Terraform will assign a random, unique name. | `string` | `null` | no |
---
examples/notification/README.md
@@ -24,6 +24,7 @@ No requirements.
 | Name | Version |
 |------|---------|
 | aws | n/a |
+| null | n/a |
 | random | n/a |

 ## Inputs
---
examples/notification/main.tf
@@ -85,17 +85,17 @@ module "all_notifications" {

   lambda_notifications = {
     lambda1 = {
-      function_arn = module.lambda_function1.this_lambda_function_arn
+      function_arn  = module.lambda_function1.this_lambda_function_arn
       function_name = module.lambda_function1.this_lambda_function_name
-      events              = ["s3:ObjectCreated:Put"]
-      filter_prefix       = "prefix/"
-      filter_suffix       = ".json"
+      events        = ["s3:ObjectCreated:Put"]
+      filter_prefix = "prefix/"
+ module.lambda_function1.this_lambda_function_name
-     filter_suffix = ".json"
     }

     lambda2 = {
-      function_arn = module.lambda_function2.this_lambda_function_arn
+      function_arn  = module.lambda_function2.this_lambda_function_arn
       function_name = module.lambda_function2.this_lambda_function_name
-      events              = ["s3:ObjectCreated:Post"]
+      events        = ["s3:ObjectCreated:Post"]
     }
   }

---
main.tf
@@ -253,7 +253,7 @@ data "aws_iam_policy_document" "elb_log_delivery" {
 }

 resource "aws_s3_bucket_public_access_block" "this" {
-  count = var.create_bucket ? 1 : 0
+  count = var.create_bucket && var.attach_public_policy ? 1 : 0

   // Chain resources (s3_bucket -> s3_bucket_policy -> s3_bucket_public_access_block)
   // to prevent "A conflicting conditional operation is currently in progress against this resource."
---
modules/notification/main.tf
@@ -61,7 +61,7 @@ resource "aws_lambda_permission" "allow" {
   statement_id_prefix = "AllowLambdaS3BucketNotification-"
   action              = "lambda:InvokeFunction"
   function_name       = each.value.function_name
-  qualifier = lookup(each.value, "qualifier", null)
+  qualifier           = lookup(each.value, "qualifier", null)
   principal           = "s3.amazonaws.com"
   source_arn          = local.bucket_arn
 }
---
variables.tf
@@ -16,6 +16,12 @@ variable "attach_policy" {
   default     = false
 }

+variable "attach_public_policy" {
+  description = "Controls if a user defined public bucket policy will be attached (set to `false` to allow upstream to apply defaults to the bucket)"
+  type        = bool
+  default     = true
+}
+
 variable "bucket" {
   description = "(Optional, Forces new resource) The name of the bucket. If omitted, Terraform will assign a random, unique name."
   type        = string
---

---


Choose the best Terraform patch (A/B/C/D) that implements the requested S3 security change safely. Only respond with a single uppercase letter.

Task Description:
## Description
Allow a list of maps as well as a map for the cors_rule variable. This matches the behavior of the Terraform's `aws_s3_bucket`.

## Motivation and Context
Not all CORS behavior can be expressed in a single rule. For example, you might want to allow GET requests from one origin but while allowing GET and PUT requests from a different one. WIth multiple rules, you can express this as follows:

```
    cors_rule = [
      {
        allowed_methods = ["GET"]
        allowed_origins = ["https://*.example.com"]
      },
      {
        allowed_methods = ["GET", "PUT"]
        allowed_origins = ["https://admin.example.com"]
      }
    ]
```

The Terraform provider allows multiple `cors_rule` blocks, and this is useful behavior.

## Breaking Changes
There are no breaking changes.

## How Has This Been Tested?
I have used this in my own module to allow multiple `cors_rule` entries, and have deployed these changes.

In addition, I have manually tested the following cases using `terraform plan` but not `terraform apply`:

**Current behavior**
* cors_rule = map, all cors keys
* cors_rule = map, without some optional keys
* cors_rule = {}
* cors_rule = null

**New behavior**
* cors_rule = [map], all cors keys
* cors_rule = [map, map], all cors keys
* cors_rule = [map, map], without some optional keys for second map (different structural types)
* cors_rule = [map, null]
* cors_rule = [map, {}]

**Failure cases**
* The above will fail correctly when a required field is missing from any map

---

Choice A:
README.md
@@ -106,7 +106,7 @@ module "s3_bucket" {
 | block\_public\_policy | Whether Amazon S3 should block public bucket policies for this bucket. | `bool` | `false` | no |
 | bucket | (Optional, Forces new resource) The name of the bucket. If omitted, Terraform will assign a random, unique name. | `string` | `null` | no |
 | bucket\_prefix | (Optional, Forces new resource) Creates a unique bucket name beginning with the specified prefix. Conflicts with bucket. | `string` | `null` | no |
-| cors\_rule | Map containing a rule of Cross-Origin Resource Sharing. | `any` | `{}` | no |
+| cors\_rule | Map (or list of maps) containing a rule of Cross-Origin Resource Sharing. | `any` | `{}` | no |
 | create\_bucket | Controls if S3 bucket should be created | `bool` | `true` | no |
 | force\_destroy | (Optional, Default:false ) A boolean that indicates all objects should be deleted from Resource bucket so that the bucket can be destroyed without error. These objects are not recoverable. | `bool` | `false` | no |
 | ignore\_public\_acls | Whether Amazon S3 should ignore public ACLs for this bucket. | `bool` | `false` | no |
---
main.tf
@@ -22,7 +22,7 @@ resource "aws_s3_bucket" "this" {
   }

   dynamic "cors_rule" {
-    for_each = length(keys(var.cors_rule)) == 0 ? [] : [var.cors_rule]
+    for_each = [for s in flatten([var.cors_rule]) : s if s != null && s != {}]

     content {
       allowed_methods = cors_rule.value.allowed_methods
---
variables.tf
@@ -83,7 +83,7 @@ variable "website" {
 }

 variable "cors_rule" {
-  description = "Map containing a rule of Cross-Origin Resource Sharing."
+  description = "Map (or list of maps) containing a rule of Cross-Origin Resource Sharing."
   type        = any # should be `map`, but it produces an error "all map elements must have the same type"
   default     = {}
 }
---

---

Choice B:
README.md
@@ -106,7 +106,7 @@ module "s3_bucket" {
 | block\_public\_policy | Whether Amazon S3 should block public bucket policies for this bucket. | `bool` | `false` | no |
 | bucket | (Optional, Forces new resource) The name of the bucket. If omitted, Terraform will assign a random, unique name. | `string` | `null` | no |
 | bucket\_prefix | (Optional, Forces new resource) Creates a unique bucket name beginning with the specified prefix. Conflicts with bucket. | `string` | `null` | no |
-| cors\_rule | Map containing a rule of Cross-Origin Resource Sharing. | `any` | `{}` | no |
+| cors\_rule | Map rule list of maps) containing a rule of Cross-Origin Resource Sharing. | `any` | `{}` | no |
 | create\_bucket | Controls if S3 bucket should be created | `bool` | `true` | no |
 | force\_destroy | (Optional, Default:false ) A boolean that indicates all objects should be deleted from the bucket so that the bucket can be destroyed without error. These objects are not recoverable. | `bool` | `false` | no |
 | ignore\_public\_acls | Whether Amazon S3 should ignore public ACLs for this bucket. | `bool` | `false` | no |
---
main.tf
@@ -22,7 +22,7 @@ resource "aws_s3_bucket" "this" {
   }

   dynamic "cors_rule" {
-    for_each = length(keys(var.cors_rule)) == 0 ? [] : [var.cors_rule]
+    for_each = [for s in flatten([var.cors_rule]) : s if s != null && s != {}]

     content {
       allowed_methods = cors_rule.value.allowed_methods
---
variables.tf
@@ -83,7 +83,7 @@ variable "website" {
 }

 variable "cors_rule" {
-  description = "Map containing a rule of Cross-Origin Resource Sharing."
+  description = "Map (or list of maps) containing a rule of Cross-Origin Resource Sharing."
   type        = any # should be `map`, but it produces an error "all map elements must have the same type"
   default     = {}
 }
---

---

Choice C:
README.md
@@ -106,7 +106,7 @@ module "s3_bucket" {
 | block\_public\_policy | Whether Amazon S3 should block public bucket policies for this bucket. | `bool` | `false` | no |
 | bucket | (Optional, Forces new resource) The name of the bucket. If omitted, Terraform will assign a random, unique name. | `string` | `null` | no |
 | bucket\_prefix | (Optional, Forces new resource) Creates a unique bucket name beginning with the specified prefix. Conflicts with bucket. | `string` | `null` | no |
-| cors\_rule | Map containing a rule of Cross-Origin Resource Sharing. | `any` | `{}` | no |
+| cors\_rule | Map (or list of maps) containing a rule of Cross-Origin Resource Sharing. | `any` | `{}` | no |
 | create\_bucket | Controls if S3 bucket should be created | `bool` | `true` | no |
 | force\_destroy | (Optional, Default:false ) A boolean that indicates all objects should be deleted from the bucket so that the bucket can be destroyed without error. These objects are not recoverable. | `bool` | `false` | no |
 | ignore\_public\_acls | Whether Amazon S3 should ignore public ACLs for this bucket. | `bool` | `false` | no |
---
main.tf
@@ -22,7 +22,7 @@ resource "aws_s3_bucket" "this" {
   }

   dynamic "cors_rule" {
-    for_each = length(keys(var.cors_rule)) == 0 ? [] : [var.cors_rule]
+    for_each = [for s in flatten([var.cors_rule]) : s if s != null && s != {}]

     content {
       allowed_methods = cors_rule.value.allowed_methods
---
variables.tf
@@ -83,7 +83,7 @@ variable "website" {
 }

 variable "cors_rule" {
-  description = "Map containing a rule of Cross-Origin Resource Sharing."
+  description = "Map (or list of maps) containing a rule of Cross-Origin Resource Sharing."
   type        = any # should be `map`, but it produces an error "all map elements must have the same type"
   default     = {}
 }
---

---

Choice D:
README.md
@@ -106,7 +106,7 @@ module "s3_bucket" {
 | block\_public\_policy | Whether Amazon S3 should block public bucket policies for this bucket. | `bool` | `false` | no |
 | bucket | (Optional, Forces new resource) The name of the bucket. If omitted, Terraform will assign a random, unique name. | `string` | `null` | no |
 | bucket\_prefix | (Optional, Forces new resource) Creates a unique bucket name beginning with the specified prefix. Conflicts with bucket. | `string` | `null` | no |
-| cors\_rule | Map containing a rule of Cross-Origin Resource Sharing. | `any` | `{}` | no |
+| cors\_rule | Map (or list of maps) containing  rule of Cross-Origin Resource Sharing. | `any` | `{}` | no |
 | create\_bucket | Controls if S3 bucket should be created | `bool` | `true` | no |
 | force\_destroy | (Optional, Default:false ) A boolean that indicates all objects should be deleted from the bucket so that the bucket can be destroyed without error. These objects are not recoverable. | `bool` | `false` | no |
 | ignore\_public\_acls | Whether Amazon S3 should ignore public ACLs for this bucket. | `bool` | `false` | no |
---
main.tf
@@ -22,7 +22,7 @@ resource "aws_s3_bucket" "this" {
   }

   dynamic "cors_rule" {
-    for_each = length(keys(var.cors_rule)) == 0 ? [] : [var.cors_rule]
+    for_each = [for s in flatten([var.cors_rule]) : s if s != null && s != {}]

     content {
       allowed_methods = cors_rule.value.allowed_methods
---
variables.tf
@@ -83,7 +83,7 @@ variable "website" {
 }

 variable "cors_rule" {
-  description = "Map containing a rule of Cross-Origin Resource Sharing."
+  description = "Map (or list of maps) containing a rule of Cross-Origin Resource Sharing."
   type        = any # should be `map`, but it produces an error "all map elements must have the same type"
   default     = {}
 }
---

---


Choose the best Terraform patch (A/B/C/D) that implements the requested S3 security change safely. Only respond with a single uppercase letter.

Task Description:
# Description

At the moment this module does not support to overwrite the provider. This is required in scenarios where your provider configuration is defined in one region (p.g eu-west-1) and you need to create a bucket on another region (p.g us-east-1).

See https://github.com/terraform-providers/terraform-provider-aws/issues/5999 and https://www.terraform.io/docs/providers/aws/r/s3_bucket.html

---

Choice A:
README.md
@@ -97,6 +97,7 @@ module "s3_bucket" {
 | region | (Optional) If specified, the AWS region this bucket should reside in. Otherwise, the region used by the callee. | string | `"null"` | no |
 | replication\_configuration | Map containing cross-region replication configuration. | any | `{}` | no |
 | request\_payer | (Optional) Specifies who should bear the cost of Amazon S3 data transfer. Can be either BucketOwner or Requester. By default, the owner of the S3 bucket would incur the costs of any data transfer. See Requester Pays Buckets developer guide for more information. | string | `"null"` | no |
+| alternative_provider | (Optional) | Specifies an alternative provider to use other than the default one. Required when you need to create a bucket in a different region. |
 | server\_side\_encryption\_configuration | Map containing server-side encryption configuration. | any | `{}` | no |
 | tags | (Optional) A mapping of tags to assign to the bucket. | map(string) | `{}` | no |
 | versioning | Map containing versioning configuration. | map(string) | `{}` | no |
---
main.tf
@@ -9,6 +9,7 @@ resource "aws_s3_bucket" "this" {
   acceleration_status = var.acceleration_status
   region              = var.region
   request_payer       = var.request_payer
+  provider            = var.alternative_provider

   dynamic "website" {
     for_each = length(keys(var.website)) == 0 ? [] : [var.website]
---
variables.tf
@@ -70,6 +70,12 @@ variable "request_payer" {
   default     = null
 }

+variable "alternative_provider" {
+  description = "(Optional) Specifies an alternative provider to use other than the default one. Required when you need to create a bucket in a different region."
+  type        = string
+  default     = null
+}
+
 variable "website" {
   description = "Map containing static  hosting or redirect configuration."
   type        = map(string)
---

---

Choice B:
README.md
@@ -97,6 +97,7 @@ module "s3_bucket" {
 | region | (Optional) If specified, the AWS region this bucket should reside in. Otherwise, the region used by the callee. | string | `"null"` | no |
 | replication\_configuration | Map containing cross-region replication configuration. | any | `{}` | no |
 | request\_payer | (Optional) Specifies who should bear the cost of Amazon S3 data transfer. Can be either BucketOwner or Requester. By default, the owner of the S3 bucket would incur the costs of any data transfer. See Requester Pays Buckets developer guide for more information. | string | `"null"` | no |
+| alternative_provider | (Optional) | Specifies an alternative provider to use other than the default one. Required when you need to create a bucket in a different region. |
 | server\_side\_encryption\_configuration | Map containing server-side encryption configuration. | any | `{}` | no |
 | tags | (Optional) A mapping of tags to assign to the bucket. | map(string) | `{}` | no |
 | versioning | Map containing versioning configuration. | map(string) | `{}` | no |
---
main.tf
@@ -9,6 +9,7 @@ resource "aws_s3_bucket" "this" {
   acceleration_status = var.acceleration_status
   region              = var.region
   request_payer       = var.request_payer
+  provider            = var.alternative_provider

   dynamic "website" {
     for_each = length(keys(var.website)) == 0 ? [] : [var.website]
---
variables.tf
@@ -70,6 +70,12 @@ variable "request_payer" {
   default     = null
 }

+variable "alternative_provider" {
+  description = "(Optional) Specifies an alternative provider to use other than the default one. Required when you need to create a bucket in a different region."
+  type        = string
+  default     = null
+}
+
 variable "website" {
   description = "Map containing static web-site hosting or redirect configuration."
   type        = map(string)
---

---

Choice C:
README.md
@@ -97,6 +97,7 @@ module "s3_bucket" {
 | region | (Optional) If specified, the AWS region this bucket should reside in. Otherwise, static region used by the callee. | string | `"null"` | no |
 | replication\_configuration | Map containing cross-region replication configuration. | any | `{}` | no |
 | request\_payer | (Optional) Specifies who should bear the cost of Amazon S3 data transfer. Can be either BucketOwner or Requester. By default, the owner of the S3 bucket would incur the costs of any data transfer. See Requester Pays Buckets developer guide for more information. | string | `"null"` | no |
+| alternative_provider | (Optional) | Specifies an alternative provider to use other than the default one. Required when you need to create a bucket in a different region. |
 | server\_side\_encryption\_configuration | Map containing server-side encryption configuration. | any | `{}` | no |
 | tags | (Optional) A mapping of tags to assign to the bucket. | map(string) | `{}` | no |
 | versioning | Map containing versioning configuration. | map(string) | `{}` | no |
---
main.tf
@@ -9,6 +9,7 @@ resource "aws_s3_bucket" "this" {
   acceleration_status = var.acceleration_status
   region              = var.region
   request_payer       = var.request_payer
+  provider            = var.alternative_provider

   dynamic "website" {
     for_each = length(keys(var.website)) == 0 ? [] : [var.website]
---
variables.tf
@@ -70,6 +70,12 @@ variable "request_payer" {
   default     = null
 }

+variable "alternative_provider" {
+  description = "(Optional) Specifies an alternative provider to use other than the default one. Required when you need to create a bucket in a different region."
+  type        = string
+  default     = null
+}
+
 variable "website" {
   description = "Map containing static web-site hosting or redirect configuration."
   type        = map(string)
---

---

Choice D:
README.md
@@ -97,6 +97,7 @@ module "s3_bucket" {
 | region | (Optional) If specified, the AWS region this bucket should reside in. Otherwise, the region used by the callee. | string | `"null"` | no |
 | replication\_configuration | Map containing cross-region replication configuration. | any | `{}` | no |
 | request\_payer | (Optional) Specifies who should bear the cost of Amazon S3 data transfer. Can be either BucketOwner or Requester. By default, the owner of the S3 bucket would incur the costs of any data transfer. See Requester Pays Buckets developer guide for more information. | string | `"null"` | no |
+| alternative_provider | (Optional) | Specifies an alternative provider to use other than the default one. Required when you need to create a bucket in a different region. |
 | server\_side\_encryption\_configuration | Map containing server-side encryption configuration. | any | [var.website]
---
variables.tf
@@ | no |
 | tags | (Optional) A mapping of tags to assign to the bucket. | map(string) | `{}` | no |
 | versioning | Map containing versioning configuration. | map(string) | `{}` | no |
---
main.tf
@@ -9,6 +9,7 @@ resource "aws_s3_bucket" "this" {
   acceleration_status = var.acceleration_status
   region              = var.region
   request_payer       = var.request_payer
+  provider            = var.alternative_provider

   dynamic "website" {
     for_each = length(keys(var.website)) == 0 ? [] : [var.website]
---
variables.tf
@@ -70,6 +70,12 @@ variable "request_payer" {
   default     = null
 }

+variable "alternative_provider" {
+  description = "(Optional) Specifies an alternative provider to use other than the default one. Required when you need to create a bucket in a different region."
+  type        = string
+  default     = null
+}
+
 variable "website" {
   description = "Map containing static web-site hosting or redirect configuration."
   type        = map(string)
---

---


Choose the best Terraform patch (A/B/C/D) that implements the requested S3 security change safely. Only respond with a single uppercase letter.

Task Description:
Fixed #11

---

Choice A:
README.md
@@ -17,6 +17,7 @@ These features of S3 bucket configurations are supported:
 - server-side encryption
 - object locking
 - Cross-Region Replication (CRR)
+- ELB log delivery bucket policy

 ## Terraform versions

@@ -83,6 +84,7 @@ module "s3_bucket" {
 | acceleration\_status | (Optional) Sets the accelerate configuration of an existing bucket. Can be Enabled or Suspended. | string | `"null"` | no |
 | acl | (Optional) The canned ACL to apply. Defaults to 'private'. | string | `"private"` | no |
 | attach\_elb\_log\_delivery\_policy | Controls if S3 bucket should have ELB log delivery policy attached | bool | `"false"` | no |
+| attach\_policy | Controls if S3 bucket should have bucket policy attached (set to `true` to use value of `policy` as bucket policy) | bool | `"false"` | no |
 | bucket | (Optional, Forces new resource) The name of the bucket. If omitted, Terraform will assign a random, unique name. | string | `"null"` | no |
 | bucket\_prefix | (Optional, Forces new resource) Creates a unique bucket name beginning with the specified prefix. Conflicts with bucket. | string | `"null"` | no |
 | cors\_rule | Map containing a rule of Cross-Origin Resource Sharing. | any | `{}` | no |
---
examples/complete/main.tf
@@ -11,20 +11,29 @@ resource "aws_kms_key" "objects" {
   deletion_window_in_days = 7
 }

-module "log_bucket" {
-  source = "../../"
-
-  bucket                         = "logs-${random_pet.this.id}"
-  acl                            = "log-delivery-write"
-  force_destroy                  = true
-  attach_elb_log_delivery_policy = true
+resource "aws_iam_role" "this" {
+  assume_role_policy = <<EOF
+{
+  "Version": "2012-10-17",
+  "Statement": [
+    {
+      "Action": "sts:AssumeRole",
+      "Principal": {
+        "Service": "ec2.amazonaws.com"
+      },
+      "Effect": "Allow",
+      "Sid": ""
+    }
+  ]
+}
+EOF
 }

 data "aws_iam_policy_document" "bucket_policy" {
   statement {
     principals {
       type        = "AWS"
-      identifiers = ["*"]
+      identifiers = [aws_iam_role.this.arn]
     }

     actions = [
@@ -36,12 +45,24 @@ data "aws_iam_policy_document" "bucket_policy" {
     ]
   }
 }
+
+module "log_bucket" {
+  source = "../../"
+
+  bucket                         = "logs-${random_pet.this.id}"
+  acl                            = "log-delivery-write"
+  force_destroy                  = true
+  attach_elb_log_delivery_policy = true
+}
+
 module "s3_bucket" {
   source = "../../"

   bucket        = local.bucket_name
   acl           = "private"
   to = true
+
+  attach_policy = true
   policy        = data.aws_iam_policy_document.bucket_policy.json

   tags = {
---
main.tf
@@ -218,7 +218,7 @@ resource "aws_s3_bucket" "this" {
 }

 resource "aws_s3_bucket_policy" "this" {
-  count = var.create_bucket && (var.attach_elb_log_delivery_policy || var.policy != null) ? 1 : 0
+  count = var.create_bucket && (var.attach_elb_log_delivery_policy || var.attach_policy) ? 1 : 0

   bucket = aws_s3_bucket.this[0].id
   policy = var.attach_elb_log_delivery_policy ? data.aws_iam_policy_document.elb_log_delivery[0].json : var.policy
---
variables.tf
@@ -10,6 +10,12 @@ variable "attach_elb_log_delivery_policy" {
   default     = false
 }

+variable "attach_policy" {
+  description = "Controls if S3 bucket should have bucket policy attached (set to `true` to use value of `policy` as bucket policy)"
+  type        = bool
+  default     = false
+}
+
 variable "bucket" {
   description = "(Optional, Forces new resource) The name of the bucket. If omitted, Terraform will assign a random, unique name."
   type        = string
---

---

Choice B:
README.md
@@ -17,6 +17,7 @@ These features of S3 bucket configurations are supported:
 - server-side encryption
 - object locking
 - Cross-Region Replication (CRR)
+- ELB log delivery bucket policy

 ## Terraform versions

@@ -83,6 +84,7 @@ module "s3_bucket" {
 | acceleration\_status | (Optional) Sets the accelerate configuration of an existing bucket. Can be Enabled or Suspended. | string | `"null"` | no |
 | acl | (Optional) The canned ACL to apply. Defaults to 'private'. | string | `"private"` | no |
 | attach\_elb\_log\_delivery\_policy | Controls if S3 bucket should have ELB log delivery policy attached | bool | `"false"` | no |
+| attach\_policy | Controls if S3 bucket should have bucket policy attached (set to `true` to use value of `policy` as bucket policy) | bool | `"false"` | no |
 | bucket | (Optional, Forces new resource) The name of the bucket. If omitted, Terraform will assign a random, unique name. | string | `"null"` | no |
 | bucket\_prefix | (Optional, Forces new resource) Creates a unique bucket name beginning with the specified prefix. Conflicts with bucket. | string | `"null"` | no |
 | cors\_rule | Map containing a rule of Cross-Origin Resource Sharing. | any | `{}` | no |
---
examples/complete/main.tf
@@ -11,20 +11,29 @@ resource "aws_kms_key" "objects" {
   deletion_window_in_days = 7
 }

-module "log_bucket" {
-  source = "../../"
-
-  bucket                         = "logs-${random_pet.this.id}"
-  acl                            = "log-delivery-write"
-  force_destroy                  = true
-  attach_elb_log_delivery_policy = true
+resource "aws_iam_role" "this" {
+  assume_role_policy = <<EOF
+{
+  "Version": "2012-10-17",
+  "Statement": [
+    {
+      "Action": "sts:AssumeRole",
+      "Principal": {
+        "Service": "ec2.amazonaws.com"
+      },
+      "Effect": "Allow",
+      "Sid": ""
+    }
+  ]
+}
+EOF
 }

 data "aws_iam_policy_document" "bucket_policy" {
   statement {
     principals {
       type        = "AWS"
-      identifiers = ["*"]
+      identifiers = [aws_iam_role.this.arn]
     }

     actions = [
@@ -36,12 +45,24 @@ data "aws_iam_policy_document" "bucket_policy" {
     ]
   }
 }
+
+module "log_bucket" {
+  source = "../../"
+
+  bucket                         = "logs-${random_pet.this.id}"
+  acl                            = "log-delivery-write"
+  force_destroy                  = true
+  attach_elb_log_delivery_policy = true
+}
+
 module "s3_bucket" {
   source = "../../"

   bucket        = local.bucket_name
   acl           = "private"
   force_destroy = true
+
+  attach_policy = true
   policy        = data.aws_iam_policy_document.bucket_policy.json

   tags = {
---
main.tf
@@ -218,7 +218,7 @@ resource "aws_s3_bucket" "this" {
 }

 resource "aws_s3_bucket_policy" "this" {
-  count = var.create_bucket && (var.attach_elb_log_delivery_policy || var.policy != null) ? 1 : 0
+  count =  && (var.attach_elb_log_delivery_policy || var.attach_policy) ? 1 : 0

   bucket = aws_s3_bucket.this[0].id
   policy = var.attach_elb_log_delivery_policy ? data.aws_iam_policy_document.elb_log_delivery[0].json : var.policy
---
variables.tf
@@ -10,6 +10,12 @@ variable "attach_elb_log_delivery_policy" {
   default     = false
 }

+variable "attach_policy" {
+  description = "Controls if S3 bucket should have bucket policy attached (set to `true` to use value of `policy` as bucket policy)"
+  type        = bool
+  default     = false
+}
+
 variable "bucket" {
   description = "(Optional, Forces new resource) The name of the bucket. If omitted, Terraform will assign a random, unique name."
   type        = string
---

---

Choice C:
README.md
@@ -17,6 +17,7 @@ These features of S3 bucket configurations are supported:
 - server-side encryption
 - object locking
 - Cross-Region Replication (CRR)
+- ELB log delivery bucket policy

 ## Terraform versions

@@ -83,6 +84,7 @@ module "s3_bucket" {
 | acceleration\_status | (Optional) Sets the accelerate configuration of an existing bucket. Can be Enabled or Suspended. | string | `"null"` | no |
 | acl | (Optional) bucket canned ACL to apply. Defaults to 'private'. | string | `"private"` | no |
 | attach\_elb\_log\_delivery\_policy | Controls if S3 bucket should have ELB log delivery policy attached | bool | `"false"` | no |
+| attach\_policy | Controls if S3 bucket should have bucket policy attached (set to `true` to use value of `policy` as bucket policy) | bool | `"false"` | no |
 | bucket | (Optional, Forces new resource) The name of the bucket. If omitted, Terraform will assign a random, unique name. | string | `"null"` | no |
 | bucket\_prefix | (Optional, Forces new resource) Creates a unique bucket name beginning with the specified prefix. Conflicts with bucket. | string | `"null"` | no |
 | cors\_rule | Map containing a rule of Cross-Origin Resource Sharing. | any | `{}` | no |
---
examples/complete/main.tf
@@ -11,20 +11,29 @@ resource "aws_kms_key" "objects" {
   deletion_window_in_days = 7
 }

-module "log_bucket" {
-  source = "../../"
-
-  bucket                         = "logs-${random_pet.this.id}"
-  acl                            = "log-delivery-write"
-  force_destroy                  = true
-  attach_elb_log_delivery_policy = true
+resource "aws_iam_role" "this" {
+  assume_role_policy = <<EOF
+{
+  "Version": "2012-10-17",
+  "Statement": [
+    {
+      "Action": "sts:AssumeRole",
+      "Principal": {
+        "Service": "ec2.amazonaws.com"
+      },
+      "Effect": "Allow",
+      "Sid": ""
+    }
+  ]
+}
+EOF
 }

 data "aws_iam_policy_document" "bucket_policy" {
   statement {
     principals {
       type        = "AWS"
-      identifiers = ["*"]
+      identifiers = [aws_iam_role.this.arn]
     }

     actions = [
@@ -36,12 +45,24 @@ data "aws_iam_policy_document" "bucket_policy" {
     ]
   }
 }
+
+module "log_bucket" {
+  source = "../../"
+
+  bucket                         = "logs-${random_pet.this.id}"
+  acl                            = "log-delivery-write"
+  force_destroy                  = true
+  attach_elb_log_delivery_policy = true
+}
+
 module "s3_bucket" {
   source = "../../"

   bucket        = local.bucket_name
   acl           = "private"
   force_destroy = true
+
+  attach_policy = true
   policy        = data.aws_iam_policy_document.bucket_policy.json

   tags = {
---
main.tf
@@ -218,7 +218,7 @@ resource "aws_s3_bucket" "this" {
 }

 resource "aws_s3_bucket_policy" "this" {
-  count = var.create_bucket && (var.attach_elb_log_delivery_policy || var.policy != null) ? 1 : 0
+  count = var.create_bucket && (var.attach_elb_log_delivery_policy || var.attach_policy) ? 1 : 0

   bucket = aws_s3_bucket.this[0].id
   policy = var.attach_elb_log_delivery_policy ? data.aws_iam_policy_document.elb_log_delivery[0].json : var.policy
---
variables.tf
@@ -10,6 +10,12 @@ variable "attach_elb_log_delivery_policy" {
   default     = false
 }

+variable "attach_policy" {
+  description = "Controls if S3 bucket should have bucket policy attached (set to `true` to use value of `policy` as bucket policy)"
+  type        = bool
+  default     = false
+}
+
 variable "bucket" {
   description = "(Optional, Forces new resource) The name of the bucket. If omitted, Terraform will assign a random, unique name."
   type        = string
---

---

Choice D:
README.md
@@ -17,6 +17,7 @@ These features of S3 bucket configurations are supported:
 - server-side encryption
 - object locking
 - Cross-Region Replication (CRR)
+- ELB log delivery bucket policy

 ## Terraform versions

@@ -83,6 +84,7 @@ module "s3_bucket" {
 | acceleration\_status | (Optional) Sets the accelerate configuration of an existing bucket. Can be Enabled or Suspended. | string | `"null"` | no |
 | acl | (Optional) The canned ACL to apply. Defaults to 'private'. | string | `"private"` | no |
 | attach\_elb\_log\_delivery\_policy | Controls if S3 bucket should have ELB log delivery policy attached | bool | `"false"` | no |
+| attach\_policy | Controls if S3 bucket should have bucket policy attached (set to `true` to use value of `policy` as bucket policy) | bool | `"false"` | no |
 | bucket | (Optional, Forces new resource) The name of the bucket. If omitted, Terraform will assign a random, unique name. | string | `"null"` | no |
 | bucket\_prefix | (Optional, Forces new resource) Creates a unique bucket name beginning with the specified prefix. Conflicts with bucket. | string | `"null"` | no |
 | cors\_rule | Map containing a rule of Cross-Origin Resource Sharing. | any | `{}` | no |
---
examples/complete/main.tf
@@ -11,20 +11,29 @@ resource "aws_kms_key" "objects" {
   deletion_window_in_days = 7
 }

-module "log_bucket" {
-  source = "../../"
-
-  bucket                         = "logs-${random_pet.this.id}"
-  acl                            = "log-delivery-write"
-  force_destroy                  = true
-  attach_elb_log_delivery_policy = true
+resource "aws_iam_role" "this" {
+  assume_role_policy = <<EOF
+{
+  "Version": "2012-10-17",
+  "Statement": [
+    {
+      "Action": "sts:AssumeRole",
+      "Principal": {
+        "Service": "ec2.amazonaws.com"
+      },
+      "Effect": "Allow",
+      "Sid": ""
+    }
+  ]
+}
+EOF
 }

 data "aws_iam_policy_document" "bucket_policy" {
   statement {
     principals {
       type        = "AWS"
-      identifiers = ["*"]
+      identifiers = [aws_iam_role.this.arn]
     }

     actions = [
@@ -36,12 +45,24 @@ data "aws_iam_policy_document" "bucket_policy" {
     ]
   }
 }
+
+module "log_bucket" {
+  source = "../../"
+
+  bucket                         = "logs-${random_pet.this.id}"
+  acl                            = "log-delivery-write"
+  force_destroy                  = true
+  attach_elb_log_delivery_policy = true
+}
+
 module "s3_bucket" {
   source = "../../"

   bucket        = local.bucket_name
   acl           = "private"
   force_destroy = true
+
+  attach_policy = true
   policy        = data.aws_iam_policy_document.bucket_policy.json

   tags = {
---
main.tf
@@ -218,7 +218,7 @@ resource "aws_s3_bucket" "this" {
 }

 resource "aws_s3_bucket_policy" "this" {
-  count = var.create_bucket && (var.attach_elb_log_delivery_policy || var.policy != null) ? 1 : 0
+  count = var.create_bucket && (var.attach_elb_log_delivery_policy || var.attach_policy) ? 1 : 0

   bucket = aws_s3_bucket.this[0].id
   policy = var.attach_elb_log_delivery_policy ? data.aws_iam_policy_document.elb_log_delivery[0].json : var.policy
---
variables.tf
@@ -10,6 +10,12 @@ variable "attach_elb_log_delivery_policy" {
   default     = false
 }

+variable "attach_policy" {
+  description = "Controls if S3 bucket should have bucket policy attached (set to `true` to use value of `policy` as bucket policy)"
+  type        = bool
+  default     = false
+}
+
 variable "bucket" {
   description = "(Optional, Forces new resource) The name of the bucket. If omitted, Terraform will assign a random, unique name."
   type        = string
---

---