diff --git a/README.md b/README.md index 14f8ec2d..72d509e2 100644 --- a/README.md +++ b/README.md @@ -213,13 +213,15 @@ Available targets: | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 0.13.0 | -| [aws](#requirement\_aws) | >= 2.33 | +| [aws](#requirement\_aws) | >= 3.0 | +| [time](#requirement\_time) | >= 0.7 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 2.33 | +| [aws](#provider\_aws) | >= 3.0 | +| [time](#provider\_time) | >= 0.7 | ## Modules @@ -236,8 +238,10 @@ Available targets: | [aws_iam_role.replication](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | | [aws_iam_role_policy_attachment.replication](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | | [aws_s3_bucket.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource | +| [aws_s3_bucket_ownership_controls.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_ownership_controls) | resource | | [aws_s3_bucket_policy.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_policy) | resource | | [aws_s3_bucket_public_access_block.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block) | resource | +| [time_sleep.wait_for_aws_s3_bucket_settings](https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/sleep) | resource | | [aws_iam_policy_document.aggregated_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | | [aws_iam_policy_document.bucket_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | | [aws_iam_policy_document.replication](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | @@ -284,6 +288,7 @@ Available targets: | [regex\_replace\_chars](#input\_regex\_replace\_chars) | Terraform regular expression (regex) string.
Characters matching the regex will be removed from the ID elements.
If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no | | [replication\_rules](#input\_replication\_rules) | DEPRECATED: Use s3\_replication\_rules instead. | `list(any)` | `null` | no | | [restrict\_public\_buckets](#input\_restrict\_public\_buckets) | Set to `false` to disable the restricting of making the bucket public | `bool` | `true` | no | +| [s3\_object\_ownership](#input\_s3\_object\_ownership) | Specifies the S3 object ownership control. Valid values are `ObjectWriter` and `BucketOwnerPreferred` | `string` | `"ObjectWriter"` | no | | [s3\_replica\_bucket\_arn](#input\_s3\_replica\_bucket\_arn) | A single S3 bucket ARN to use for all replication rules.
Note: The destination bucket can be specified in the replication rule itself
(which allows for multiple destinations), in which case it will take precedence over this variable. | `string` | `""` | no | | [s3\_replication\_enabled](#input\_s3\_replication\_enabled) | Set this to true and specify `s3_replication_rules` to enable replication. `versioning_enabled` must also be `true`. | `bool` | `false` | no | | [s3\_replication\_rules](#input\_s3\_replication\_rules) | Specifies the replication rules for S3 bucket replication if enabled. You must also set s3\_replication\_enabled to true. | `list(any)` | `null` | no | diff --git a/docs/terraform.md b/docs/terraform.md index 661c80a4..02eca5f2 100644 --- a/docs/terraform.md +++ b/docs/terraform.md @@ -4,13 +4,15 @@ | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 0.13.0 | -| [aws](#requirement\_aws) | >= 2.33 | +| [aws](#requirement\_aws) | >= 3.0 | +| [time](#requirement\_time) | >= 0.7 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 2.33 | +| [aws](#provider\_aws) | >= 3.0 | +| [time](#provider\_time) | >= 0.7 | ## Modules @@ -27,8 +29,10 @@ | [aws_iam_role.replication](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | | [aws_iam_role_policy_attachment.replication](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | | [aws_s3_bucket.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource | +| [aws_s3_bucket_ownership_controls.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_ownership_controls) | resource | | [aws_s3_bucket_policy.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_policy) | resource | | [aws_s3_bucket_public_access_block.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block) | resource | +| [time_sleep.wait_for_aws_s3_bucket_settings](https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/sleep) | resource | | [aws_iam_policy_document.aggregated_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | | [aws_iam_policy_document.bucket_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | | [aws_iam_policy_document.replication](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | @@ -75,6 +79,7 @@ | [regex\_replace\_chars](#input\_regex\_replace\_chars) | Terraform regular expression (regex) string.
Characters matching the regex will be removed from the ID elements.
If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no | | [replication\_rules](#input\_replication\_rules) | DEPRECATED: Use s3\_replication\_rules instead. | `list(any)` | `null` | no | | [restrict\_public\_buckets](#input\_restrict\_public\_buckets) | Set to `false` to disable the restricting of making the bucket public | `bool` | `true` | no | +| [s3\_object\_ownership](#input\_s3\_object\_ownership) | Specifies the S3 object ownership control. Valid values are `ObjectWriter` and `BucketOwnerPreferred` | `string` | `"ObjectWriter"` | no | | [s3\_replica\_bucket\_arn](#input\_s3\_replica\_bucket\_arn) | A single S3 bucket ARN to use for all replication rules.
Note: The destination bucket can be specified in the replication rule itself
(which allows for multiple destinations), in which case it will take precedence over this variable. | `string` | `""` | no | | [s3\_replication\_enabled](#input\_s3\_replication\_enabled) | Set this to true and specify `s3_replication_rules` to enable replication. `versioning_enabled` must also be `true`. | `bool` | `false` | no | | [s3\_replication\_rules](#input\_s3\_replication\_rules) | Specifies the replication rules for S3 bucket replication if enabled. You must also set s3\_replication\_enabled to true. | `list(any)` | `null` | no | diff --git a/main.tf b/main.tf index 3a961dd4..34d7acd1 100644 --- a/main.tf +++ b/main.tf @@ -388,3 +388,22 @@ resource "aws_s3_bucket_public_access_block" "default" { ignore_public_acls = var.ignore_public_acls restrict_public_buckets = var.restrict_public_buckets } + +# Per https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html +resource "aws_s3_bucket_ownership_controls" "default" { + count = local.enabled ? 1 : 0 + bucket = join("", aws_s3_bucket.default.*.id) + + rule { + object_ownership = var.s3_object_ownership + } + depends_on = [time_sleep.wait_for_aws_s3_bucket_settings] +} + +# Workaround S3 eventual consistency for settings objects +resource "time_sleep" "wait_for_aws_s3_bucket_settings" { + count = local.enabled ? 1 : 0 + depends_on = [aws_s3_bucket_public_access_block.default, aws_s3_bucket_policy.default] + create_duration = "30s" + destroy_duration = "30s" +} diff --git a/test/src/examples_complete_test.go b/test/src/examples_complete_test.go index 99fb3768..4388418e 100644 --- a/test/src/examples_complete_test.go +++ b/test/src/examples_complete_test.go @@ -216,7 +216,6 @@ func TestExamplesCompleteWithReplication(t *testing.T) { // Verify we're getting back the outputs we expect assert.NotEmptyf(t, s3ReplicationRoleArn, "If replication is enabled, we should get a Replication Role ARN.") - } func TestExamplesCompleteWithPrivilegedPrincipals(t *testing.T) { @@ -373,5 +372,4 @@ func TestExamplesCompleteDisabled(t *testing.T) { // Verify we're getting back the outputs we expect assert.Empty(t, s3ReplicationBucketId, "When disabled, module should have no outputs.") - -} +} \ No newline at end of file diff --git a/variables.tf b/variables.tf index b93c2c3c..46390978 100644 --- a/variables.tf +++ b/variables.tf @@ -280,3 +280,9 @@ variable "transfer_acceleration_enabled" { default = false description = "Set this to true to enable S3 Transfer Acceleration for the bucket." } + +variable "s3_object_ownership" { + type = string + default = "ObjectWriter" + description = "Specifies the S3 object ownership control. Valid values are `ObjectWriter` and `BucketOwnerPreferred`" +} diff --git a/versions.tf b/versions.tf index 9d8788f2..ac1455dc 100644 --- a/versions.tf +++ b/versions.tf @@ -4,7 +4,11 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = ">= 2.33" + version = ">= 3.0" + } + time = { + source = "hashicorp/time" + version = ">= 0.7" } } }