From 9d0aca9760f9cafc359561ad4afd13d8457d391d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Castrelo=20Suarez?= Date: Mon, 15 Jun 2026 16:19:45 +0200 Subject: [PATCH 1/8] docs(aws-s3): update docs with account 12 characters and git example --- modules/aws-s3/docs/header.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/aws-s3/docs/header.md b/modules/aws-s3/docs/header.md index 693e360e6..df813cf6d 100644 --- a/modules/aws-s3/docs/header.md +++ b/modules/aws-s3/docs/header.md @@ -29,7 +29,7 @@ It is flexible, production-ready, and easy to integrate into existing infrastruc ```hcl module "s3" { - source = "github.com/prefapp/tfm/modules/aws-s3" + source = "git::https://github.com/prefapp/tfm.git//modules/aws-s3?ref=aws-s3-v0.1.1" bucket = "my-bucket" } ``` @@ -38,12 +38,12 @@ module "s3" { ```hcl module "s3" { - source = "github.com/prefapp/tfm/modules/aws-s3" + source = "git::https://github.com/prefapp/tfm.git//modules/aws-s3?ref=aws-s3-v0.1.1" bucket = "my-bucket-origin" region = "eu-west-1" s3_bucket_versioning = "Enabled" s3_replication_destination = { - account = "1122334455" + account = "112233445566" bucket_arn = "arn:aws:s3:::my-bucket-destination" storage_class = "STANDARD" } @@ -54,14 +54,14 @@ module "s3" { ```hcl module "s3" { - source = "github.com/prefapp/tfm/modules/aws-s3" + source = "git::https://github.com/prefapp/tfm.git//modules/aws-s3?ref=aws-s3-v0.1.1" bucket = "my-bucket-origin" region = "eu-west-1" s3_bucket_versioning = "Enabled" s3_replication_source = { - account = "5544332211" - role_arn = "arn:aws:iam::5544332211:role/my-bucket-origin-replication" + account = "665544332211" + role_arn = "arn:aws:iam::665544332211:role/my-bucket-origin-replication" } } ``` From b51cfd714f8d3b49dd5bebc551232113ee7b45a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Castrelo=20Suarez?= Date: Mon, 15 Jun 2026 16:20:10 +0200 Subject: [PATCH 2/8] docs(aws-s3): update examples with 12 digits accounts --- .../minimal_destination_source_and_destination/main.tf | 4 ++-- modules/aws-s3/_examples/minimal_replication/main.tf | 2 +- modules/aws-s3/_examples/minimal_source/main.tf | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/aws-s3/_examples/minimal_destination_source_and_destination/main.tf b/modules/aws-s3/_examples/minimal_destination_source_and_destination/main.tf index 90924bec9..8ed53b942 100644 --- a/modules/aws-s3/_examples/minimal_destination_source_and_destination/main.tf +++ b/modules/aws-s3/_examples/minimal_destination_source_and_destination/main.tf @@ -25,9 +25,9 @@ module "s3" { role_arn = "arn:aws:iam::1122334455:role/o-a-d-replication" } s3_replication_destination = { - account = "1122334455" + account = "112233445566" bucket_arn = "arn:aws:s3:::o-a-d" storage_class = "STANDARD" } -} \ No newline at end of file +} diff --git a/modules/aws-s3/_examples/minimal_replication/main.tf b/modules/aws-s3/_examples/minimal_replication/main.tf index 89f9e4384..a99168d44 100644 --- a/modules/aws-s3/_examples/minimal_replication/main.tf +++ b/modules/aws-s3/_examples/minimal_replication/main.tf @@ -22,7 +22,7 @@ module "s3" { s3_bucket_versioning = "Enabled" s3_replication_destination = { - account = "1112222333" + account = "112233445566" bucket_arn = "arn:aws:s3:::my-destination" storage_class = "STANDARD" } diff --git a/modules/aws-s3/_examples/minimal_source/main.tf b/modules/aws-s3/_examples/minimal_source/main.tf index 359841ea6..49d037b32 100644 --- a/modules/aws-s3/_examples/minimal_source/main.tf +++ b/modules/aws-s3/_examples/minimal_source/main.tf @@ -23,9 +23,9 @@ module "s3" { s3_bucket_versioning = "Enabled" s3_replication_destination = { - account = "1122334455" + account = "112233445566" bucket_arn = "arn:aws:s3:::destination-bucket" storage_class = "STANDARD" } -} \ No newline at end of file +} From 5006c83343ff66315f60b0f4fabaad8b8b71ddf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Castrelo=20Suarez?= Date: Mon, 15 Jun 2026 16:20:40 +0200 Subject: [PATCH 3/8] fix(aws-s3): update issue with vars --- modules/aws-s3/local.tf | 7 ++++++- modules/aws-s3/variables.tf | 5 ----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/aws-s3/local.tf b/modules/aws-s3/local.tf index 23df10e7a..0fcb161bd 100644 --- a/modules/aws-s3/local.tf +++ b/modules/aws-s3/local.tf @@ -1,3 +1,8 @@ locals { + # Validate that if s3_replication_destination is configured, versioning must be enabled + validate_replication_versioning = ( + var.s3_replication_destination == null || var.s3_bucket_versioning == "Enabled" + ) ? true : file("ERROR: When configuring s3_replication_destination, s3_bucket_versioning must be set to \"Enabled\".") + lifecycle_rules = (var.s3_replication_destination != null || var.s3_bucket_versioning == "Enabled") ? concat(var.lifecycle_rules, var.default_lifecycle_rules) : var.lifecycle_rules -} \ No newline at end of file +} diff --git a/modules/aws-s3/variables.tf b/modules/aws-s3/variables.tf index 505665044..ddccb8fe0 100644 --- a/modules/aws-s3/variables.tf +++ b/modules/aws-s3/variables.tf @@ -182,11 +182,6 @@ variable "s3_replication_destination" { })) }) default = null - - validation { - condition = var.s3_replication_destination == null || var.s3_bucket_versioning == "Enabled" - error_message = "When configuring s3_replication_destination, s3_bucket_versioning must be set to \"Enabled\"." - } } ## Replication variables From 1659b8112c396d6940efe2363a6e1ba2cbc881c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Castrelo=20Suarez?= Date: Mon, 15 Jun 2026 16:20:48 +0200 Subject: [PATCH 4/8] docs(aws-s3): update examples with 12 digits accounts --- modules/aws-s3/README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/aws-s3/README.md b/modules/aws-s3/README.md index bc91fb083..d49b9bfa4 100644 --- a/modules/aws-s3/README.md +++ b/modules/aws-s3/README.md @@ -30,7 +30,7 @@ It is flexible, production-ready, and easy to integrate into existing infrastruc ```hcl module "s3" { - source = "github.com/prefapp/tfm/modules/aws-s3" + source = "git::https://github.com/prefapp/tfm.git//modules/aws-s3?ref=aws-s3-v0.1.1" bucket = "my-bucket" } ``` @@ -39,12 +39,12 @@ module "s3" { ```hcl module "s3" { - source = "github.com/prefapp/tfm/modules/aws-s3" + source = "git::https://github.com/prefapp/tfm.git//modules/aws-s3?ref=aws-s3-v0.1.1" bucket = "my-bucket-origin" region = "eu-west-1" s3_bucket_versioning = "Enabled" s3_replication_destination = { - account = "1122334455" + account = "112233445566" bucket_arn = "arn:aws:s3:::my-bucket-destination" storage_class = "STANDARD" } @@ -55,14 +55,14 @@ module "s3" { ```hcl module "s3" { - source = "github.com/prefapp/tfm/modules/aws-s3" + source = "git::https://github.com/prefapp/tfm.git//modules/aws-s3?ref=aws-s3-v0.1.1" bucket = "my-bucket-origin" region = "eu-west-1" s3_bucket_versioning = "Enabled" s3_replication_source = { - account = "5544332211" - role_arn = "arn:aws:iam::5544332211:role/my-bucket-origin-replication" + account = "665544332211" + role_arn = "arn:aws:iam::665544332211:role/my-bucket-origin-replication" } } ``` @@ -107,7 +107,7 @@ The module is organized with the following directory and file structure: | Name | Version | |------|---------| -| [aws](#provider\_aws) | ~> 6.2 | +| [aws](#provider\_aws) | 6.30.0 | ## Modules From ce180c81038c20d129ad60653b647aa238127b2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Castrelo=20Suarez?= Date: Tue, 16 Jun 2026 09:30:32 +0200 Subject: [PATCH 5/8] feat(aws-s3): update replication module for avoid issues --- modules/aws-s3/local.tf | 14 +++++++++----- modules/aws-s3/main.tf | 4 ++-- modules/aws-s3/replication.tf | 13 ++++++++----- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/modules/aws-s3/local.tf b/modules/aws-s3/local.tf index 0fcb161bd..ab28b5ac1 100644 --- a/modules/aws-s3/local.tf +++ b/modules/aws-s3/local.tf @@ -1,8 +1,12 @@ locals { - # Validate that if s3_replication_destination is configured, versioning must be enabled - validate_replication_versioning = ( - var.s3_replication_destination == null || var.s3_bucket_versioning == "Enabled" - ) ? true : file("ERROR: When configuring s3_replication_destination, s3_bucket_versioning must be set to \"Enabled\".") + lifecycle_rules = (var.s3_replication_destination != null || var.s3_replication_source != null || var.s3_bucket_versioning == "Enabled") ? concat(var.lifecycle_rules, var.default_lifecycle_rules) : var.lifecycle_rules +} - lifecycle_rules = (var.s3_replication_destination != null || var.s3_bucket_versioning == "Enabled") ? concat(var.lifecycle_rules, var.default_lifecycle_rules) : var.lifecycle_rules +check "replication_requires_enabled_versioning" { + assert { + condition = ( + var.s3_replication_destination == null && var.s3_replication_source == null + ) || var.s3_bucket_versioning == "Enabled" + error_message = "s3_bucket_versioning must be set to \"Enabled\" when s3_replication_destination or s3_replication_source is configured." + } } diff --git a/modules/aws-s3/main.tf b/modules/aws-s3/main.tf index ecadc3b8f..6b3695cb1 100644 --- a/modules/aws-s3/main.tf +++ b/modules/aws-s3/main.tf @@ -106,8 +106,8 @@ data "aws_iam_policy_document" "source_replication_s3_policy_with_https_policy" ## Bucket Versioning resource "aws_s3_bucket_versioning" "this" { - count = var.create_bucket ? 1 : 0 - bucket = aws_s3_bucket.this[0].id + count = (var.create_bucket || var.s3_replication_destination != null || var.s3_replication_source != null) ? 1 : 0 + bucket = var.create_bucket ? aws_s3_bucket.this[0].id : data.aws_s3_bucket.this[0].id region = var.region versioning_configuration { status = var.s3_bucket_versioning diff --git a/modules/aws-s3/replication.tf b/modules/aws-s3/replication.tf index 11befb3b4..95e8e95f0 100644 --- a/modules/aws-s3/replication.tf +++ b/modules/aws-s3/replication.tf @@ -1,10 +1,13 @@ resource "aws_s3_bucket_replication_configuration" "origin_to_destination" { - count = var.s3_replication_destination != null ? 1 : 0 - depends_on = [aws_s3_bucket_versioning.this] - region = var.region - role = aws_iam_role.replication[0].arn - bucket = var.create_bucket ? aws_s3_bucket.this[0].id : data.aws_s3_bucket.this[0].id + count = var.s3_replication_destination != null ? 1 : 0 + depends_on = [ + aws_s3_bucket_versioning.this, + aws_iam_role_policy_attachment.replication, + ] + region = var.region + role = aws_iam_role.replication[0].arn + bucket = var.create_bucket ? aws_s3_bucket.this[0].id : data.aws_s3_bucket.this[0].id rule { id = "origin-to-destination" From d9c9ed075cea04a3cf8b70dd640e7a38e14d71d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Castrelo=20Suarez?= Date: Tue, 16 Jun 2026 09:31:00 +0200 Subject: [PATCH 6/8] docs(aws-s3): added avise for creation replication --- modules/aws-s3/README.md | 21 +++++++++++++++++++++ modules/aws-s3/docs/header.md | 21 +++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/modules/aws-s3/README.md b/modules/aws-s3/README.md index d49b9bfa4..c6fcd7ac2 100644 --- a/modules/aws-s3/README.md +++ b/modules/aws-s3/README.md @@ -24,6 +24,27 @@ It is flexible, production-ready, and easy to integrate into existing infrastruc - **IAM role** for replication - **Support for existing buckets** +## ⚠️ Important: Replication Setup Order + +When setting up S3 replication between buckets, follow this order to avoid failures: + +1. **Create the destination bucket first** (without any replication source configuration) + - Deploy the destination bucket without `s3_replication_source` parameter + +2. **Apply replication source configuration** + - Deploy the source bucket with `s3_replication_destination` configured + - This generates the IAM role and policies needed for replication + +3. **Configure destination to accept replication** + - Update the destination bucket Terraform with the `s3_replication_source` parameter + - Use the role ARN generated from step 2 + - Apply the full Terraform configuration + +This two-stage approach ensures that: +- IAM roles and policies are properly propagated across accounts +- The destination bucket exists before the source tries to replicate to it +- Cross-account permissions are correctly established before replication starts + ## Basic Usage ### Minimal Example (S3 bucket) diff --git a/modules/aws-s3/docs/header.md b/modules/aws-s3/docs/header.md index df813cf6d..7a6a82b3a 100644 --- a/modules/aws-s3/docs/header.md +++ b/modules/aws-s3/docs/header.md @@ -23,6 +23,27 @@ It is flexible, production-ready, and easy to integrate into existing infrastruc - **IAM role** for replication - **Support for existing buckets** +## ⚠️ Important: Replication Setup Order + +When setting up S3 replication between buckets, follow this order to avoid failures: + +1. **Create the destination bucket first** (without any replication source configuration) + - Deploy the destination bucket without `s3_replication_source` parameter + +2. **Apply replication source configuration** + - Deploy the source bucket with `s3_replication_destination` configured + - This generates the IAM role and policies needed for replication + +3. **Configure destination to accept replication** + - Update the destination bucket Terraform with the `s3_replication_source` parameter + - Use the role ARN generated from step 2 + - Apply the full Terraform configuration + +This two-stage approach ensures that: +- IAM roles and policies are properly propagated across accounts +- The destination bucket exists before the source tries to replicate to it +- Cross-account permissions are correctly established before replication starts + ## Basic Usage ### Minimal Example (S3 bucket) From 85b6b6ad28fc21665b7571ae02638512380e3bf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Castrelo?= <46498851+kastras@users.noreply.github.com> Date: Tue, 16 Jun 2026 09:48:37 +0200 Subject: [PATCH 7/8] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- modules/aws-s3/docs/header.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/aws-s3/docs/header.md b/modules/aws-s3/docs/header.md index 7a6a82b3a..903dfd516 100644 --- a/modules/aws-s3/docs/header.md +++ b/modules/aws-s3/docs/header.md @@ -39,7 +39,7 @@ When setting up S3 replication between buckets, follow this order to avoid failu - Use the role ARN generated from step 2 - Apply the full Terraform configuration -This two-stage approach ensures that: +This three-stage approach ensures that: - IAM roles and policies are properly propagated across accounts - The destination bucket exists before the source tries to replicate to it - Cross-account permissions are correctly established before replication starts From 004b09624d3eac5862f4ddcf1aa9ebc132ff6e5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Castrelo?= <46498851+kastras@users.noreply.github.com> Date: Tue, 16 Jun 2026 09:48:56 +0200 Subject: [PATCH 8/8] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- modules/aws-s3/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/aws-s3/README.md b/modules/aws-s3/README.md index c6fcd7ac2..954021494 100644 --- a/modules/aws-s3/README.md +++ b/modules/aws-s3/README.md @@ -40,7 +40,7 @@ When setting up S3 replication between buckets, follow this order to avoid failu - Use the role ARN generated from step 2 - Apply the full Terraform configuration -This two-stage approach ensures that: +This three-stage approach ensures that: - IAM roles and policies are properly propagated across accounts - The destination bucket exists before the source tries to replicate to it - Cross-account permissions are correctly established before replication starts