From ba905cd2a364f74ece63b9b550513db460aa6497 Mon Sep 17 00:00:00 2001 From: Nuno Pereira Date: Mon, 13 Oct 2025 13:50:52 +0000 Subject: [PATCH 1/6] chore: creates example to replicate issue --- examples/lifecycle-n-replication/iam.tf | 65 ++++++ examples/lifecycle-n-replication/main.tf | 199 +++++++++++++++++++ examples/lifecycle-n-replication/versions.tf | 14 ++ 3 files changed, 278 insertions(+) create mode 100644 examples/lifecycle-n-replication/iam.tf create mode 100644 examples/lifecycle-n-replication/main.tf create mode 100644 examples/lifecycle-n-replication/versions.tf diff --git a/examples/lifecycle-n-replication/iam.tf b/examples/lifecycle-n-replication/iam.tf new file mode 100644 index 00000000..8371a90a --- /dev/null +++ b/examples/lifecycle-n-replication/iam.tf @@ -0,0 +1,65 @@ +resource "aws_iam_role" "replication" { + name = "s3-bucket-replication-${random_pet.this.id}" + + assume_role_policy = < Date: Mon, 13 Oct 2025 14:41:23 +0000 Subject: [PATCH 2/6] fix: lifecycle config depends on replication --- main.tf | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/main.tf b/main.tf index 989dea1f..56c5e4e0 100644 --- a/main.tf +++ b/main.tf @@ -388,8 +388,12 @@ resource "aws_s3_bucket_lifecycle_configuration" "this" { } } - # Must have bucket versioning enabled first - depends_on = [aws_s3_bucket_versioning.this] + depends_on = [ + # Must have bucket versioning enabled first + aws_s3_bucket_versioning.this, + # Must wait for replication configuration to propagate + aws_s3_bucket_replication_configuration.this + ] } resource "aws_s3_bucket_object_lock_configuration" "this" { From 6ac1b06424617ba70a26f2ce12c0073c7d6d5ce9 Mon Sep 17 00:00:00 2001 From: Nuno Pereira Date: Tue, 14 Oct 2025 10:21:17 +0200 Subject: [PATCH 3/6] chore: formatting fixes --- examples/lifecycle-n-replication/main.tf | 86 ++++++++++++------------ 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/examples/lifecycle-n-replication/main.tf b/examples/lifecycle-n-replication/main.tf index edd48c20..add385f5 100644 --- a/examples/lifecycle-n-replication/main.tf +++ b/examples/lifecycle-n-replication/main.tf @@ -49,16 +49,16 @@ module "bucket_source" { delete_marker_replication = true destination = { - bucket = "arn:aws:s3:::${local.replica_bucket_name}" + bucket = "arn:aws:s3:::${local.replica_bucket_name}" replica_kms_key_id = aws_kms_key.replica.arn metrics = { - status = "Enabled" + status = "Enabled" minutes = 15 } replication_time = { - status = "Enabled" + status = "Enabled" minutes = 15 } } @@ -69,16 +69,16 @@ module "bucket_source" { } } }, - + { - id = "custom-additional-rule", - priority = 15, + id = "custom-additional-rule", + priority = 15, delete_marker_replication = true destination = { bucket = "arn:aws:s3:::${local.replica_bucket_name}" replica_kms_key_id = aws_kms_key.replica.arn - storage_class = "STANDARD_IA" + storage_class = "STANDARD_IA" } filter = { @@ -101,16 +101,16 @@ module "bucket_source" { delete_marker_replication = true destination = { - bucket = "arn:aws:s3:::${local.replica_bucket_name}" + bucket = "arn:aws:s3:::${local.replica_bucket_name}" replica_kms_key_id = aws_kms_key.replica.arn metrics = { - status = "Enabled" + status = "Enabled" minutes = 15 } replication_time = { - status = "Enabled" + status = "Enabled" minutes = 15 } } @@ -127,52 +127,52 @@ module "bucket_source" { # Lifecycle lifecycle_rule = [ { - id = "abort-incomplete-multipart-upload" - status = "Enabled" + id = "abort-incomplete-multipart-upload" + status = "Enabled" - abort_incomplete_multipart_upload = { - days_after_initiation = 35 - } + abort_incomplete_multipart_upload = { + days_after_initiation = 35 + } - filter = { - } + filter = { + } - noncurrent_version_expiration = { - noncurrent_days = 35 - } + noncurrent_version_expiration = { + noncurrent_days = 35 + } }, { - id = "log1" - status = "Enabled" + id = "log1" + status = "Enabled" - abort_incomplete_multipart_upload = { - days_after_initiation = 7 - } + abort_incomplete_multipart_upload = { + days_after_initiation = 7 + } - filter = { - } + filter = { + } - noncurrent_version_expiration = { - noncurrent_days = 300 - } + noncurrent_version_expiration = { + noncurrent_days = 300 + } - noncurrent_version_transition = { - noncurrent_days = 30 - storage_class = "STANDARD_IA" - } - noncurrent_version_transition = { - noncurrent_days = 60 - storage_class = "ONEZONE_IA" - } - noncurrent_version_transition = { - noncurrent_days = 90 - storage_class = "GLACIER" - } + noncurrent_version_transition = { + noncurrent_days = 30 + storage_class = "STANDARD_IA" + } + noncurrent_version_transition = { + noncurrent_days = 60 + storage_class = "ONEZONE_IA" + } + noncurrent_version_transition = { + noncurrent_days = 90 + storage_class = "GLACIER" + } } ] - depends_on = [ module.bucket_replica ] + depends_on = [module.bucket_replica] } resource "aws_kms_key" "replica" { From 9debc421393494e95e84140248bf739873d6b0ad Mon Sep 17 00:00:00 2001 From: Nuno Pereira Date: Tue, 14 Oct 2025 10:43:16 +0200 Subject: [PATCH 4/6] chore: fix linting deffects --- examples/lifecycle-n-replication/main.tf | 2 +- examples/lifecycle-n-replication/outputs.tf | 39 +++++++++++++++++++ examples/lifecycle-n-replication/variables.tf | 0 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 examples/lifecycle-n-replication/outputs.tf create mode 100644 examples/lifecycle-n-replication/variables.tf diff --git a/examples/lifecycle-n-replication/main.tf b/examples/lifecycle-n-replication/main.tf index add385f5..526be4c0 100644 --- a/examples/lifecycle-n-replication/main.tf +++ b/examples/lifecycle-n-replication/main.tf @@ -20,7 +20,7 @@ resource "random_pet" "this" { length = 2 } -module "bucket_source" { +module "s3_bucket" { source = "../../" providers = { diff --git a/examples/lifecycle-n-replication/outputs.tf b/examples/lifecycle-n-replication/outputs.tf new file mode 100644 index 00000000..3c66187e --- /dev/null +++ b/examples/lifecycle-n-replication/outputs.tf @@ -0,0 +1,39 @@ +output "s3_bucket_id" { + description = "The name of the bucket." + value = module.s3_bucket.s3_bucket_id +} + +output "s3_bucket_arn" { + description = "The ARN of the bucket. Will be of format arn:aws:s3:::bucketname." + value = module.s3_bucket.s3_bucket_arn +} + +output "s3_bucket_bucket_domain_name" { + description = "The bucket domain name. Will be of format bucketname.s3.amazonaws.com." + value = module.s3_bucket.s3_bucket_bucket_domain_name +} + +output "s3_bucket_bucket_regional_domain_name" { + description = "The bucket region-specific domain name. The bucket domain name including the region name, please refer here for format. Note: The AWS CloudFront allows specifying S3 region-specific endpoint when creating S3 origin, it will prevent redirect issues from CloudFront to S3 Origin URL." + value = module.s3_bucket.s3_bucket_bucket_regional_domain_name +} + +output "s3_bucket_hosted_zone_id" { + description = "The Route 53 Hosted Zone ID for this bucket's region." + value = module.s3_bucket.s3_bucket_hosted_zone_id +} + +output "s3_bucket_region" { + description = "The AWS region this bucket resides in." + value = module.s3_bucket.s3_bucket_region +} + +output "s3_bucket_website_endpoint" { + description = "The website endpoint, if the bucket is configured with a website. If not, this will be an empty string." + value = module.s3_bucket.s3_bucket_website_endpoint +} + +output "s3_bucket_website_domain" { + description = "The domain of the website endpoint, if the bucket is configured with a website. If not, this will be an empty string. This is used to create Route 53 alias records. " + value = module.s3_bucket.s3_bucket_website_domain +} diff --git a/examples/lifecycle-n-replication/variables.tf b/examples/lifecycle-n-replication/variables.tf new file mode 100644 index 00000000..e69de29b From 898c9f50b83c2155c45d9c87c0563d5d78762454 Mon Sep 17 00:00:00 2001 From: Nuno Pereira Date: Tue, 14 Oct 2025 12:00:19 +0200 Subject: [PATCH 5/6] chore: simplifies example --- examples/lifecycle-n-replication/main.tf | 87 ------------------------ 1 file changed, 87 deletions(-) diff --git a/examples/lifecycle-n-replication/main.tf b/examples/lifecycle-n-replication/main.tf index 526be4c0..dc1deb41 100644 --- a/examples/lifecycle-n-replication/main.tf +++ b/examples/lifecycle-n-replication/main.tf @@ -41,35 +41,6 @@ module "s3_bucket" { role = aws_iam_role.replication.arn rules = [ - { - id = "built-in-rule-repl1" - priority = 10 - status = true - - delete_marker_replication = true - - destination = { - bucket = "arn:aws:s3:::${local.replica_bucket_name}" - replica_kms_key_id = aws_kms_key.replica.arn - - metrics = { - status = "Enabled" - minutes = 15 - } - - replication_time = { - status = "Enabled" - minutes = 15 - } - } - - source_selection_criteria = { - sse_kms_encrypted_objects = { - enabled = true - } - } - }, - { id = "custom-additional-rule", priority = 15, @@ -92,35 +63,6 @@ module "s3_bucket" { } }, - - { - id = "built-in-rule-repl2" - priority = 20 - status = true - - delete_marker_replication = true - - destination = { - bucket = "arn:aws:s3:::${local.replica_bucket_name}" - replica_kms_key_id = aws_kms_key.replica.arn - - metrics = { - status = "Enabled" - minutes = 15 - } - - replication_time = { - status = "Enabled" - minutes = 15 - } - } - - source_selection_criteria = { - sse_kms_encrypted_objects = { - enabled = true - } - } - } ] } @@ -141,35 +83,6 @@ module "s3_bucket" { noncurrent_days = 35 } }, - - { - id = "log1" - status = "Enabled" - - abort_incomplete_multipart_upload = { - days_after_initiation = 7 - } - - filter = { - } - - noncurrent_version_expiration = { - noncurrent_days = 300 - } - - noncurrent_version_transition = { - noncurrent_days = 30 - storage_class = "STANDARD_IA" - } - noncurrent_version_transition = { - noncurrent_days = 60 - storage_class = "ONEZONE_IA" - } - noncurrent_version_transition = { - noncurrent_days = 90 - storage_class = "GLACIER" - } - } ] depends_on = [module.bucket_replica] From d09c21c81a8cd938976012b4c39307a650a86222 Mon Sep 17 00:00:00 2001 From: Nuno Pereira Date: Wed, 15 Oct 2025 11:52:35 +0200 Subject: [PATCH 6/6] chore: removes lifecycle-n-replication example --- examples/lifecycle-n-replication/iam.tf | 65 ---------- examples/lifecycle-n-replication/main.tf | 112 ------------------ examples/lifecycle-n-replication/outputs.tf | 39 ------ examples/lifecycle-n-replication/variables.tf | 0 examples/lifecycle-n-replication/versions.tf | 14 --- 5 files changed, 230 deletions(-) delete mode 100644 examples/lifecycle-n-replication/iam.tf delete mode 100644 examples/lifecycle-n-replication/main.tf delete mode 100644 examples/lifecycle-n-replication/outputs.tf delete mode 100644 examples/lifecycle-n-replication/variables.tf delete mode 100644 examples/lifecycle-n-replication/versions.tf diff --git a/examples/lifecycle-n-replication/iam.tf b/examples/lifecycle-n-replication/iam.tf deleted file mode 100644 index 8371a90a..00000000 --- a/examples/lifecycle-n-replication/iam.tf +++ /dev/null @@ -1,65 +0,0 @@ -resource "aws_iam_role" "replication" { - name = "s3-bucket-replication-${random_pet.this.id}" - - assume_role_policy = <