Terraform aws_s3_bucket_replication_configuration 无法使用 for_each 生成多个规则

Terraform aws_s3_bucket_replication_configuration can't generate multiple rules with for_each

我有一个具有以下“文件夹”结构的 S3 存储桶:

Bucket1----> /Partner1 ----> /Client1 ----> /User1
        |               |              |--> /User2
        |               |
        |               |--> /Client2 ----> /User1
        |
        |--> /Partner2 ----> /Client1 ----> /User1

等等。

我正在尝试设置从这个存储桶到另一个存储桶的复制,以便将文件放在

Bucket1/Partner1/client1/User1/ 应该复制到 Bucket2/Partner1/client1/User1/,

Bucket1/Partner2/client1/User2/ 应该复制到 Bucket2/Partner2/client1/User2/,

等等。

我正在尝试使用以下 terraform 代码实现此目的:

locals {
 s3_folders = [
  "Partner1/client1/User1",
  "Partner1/client1/User2",
  "Partner1/client1/User3",
  "Partner1/client1/User4",
  "Partner1/client1/User5",
  "Partner1/client2/User1",
  "Partner1/client3/User1",
  "Partner2/client1/User1",
  "Partner3/client1/User1"
 ]
}

resource "aws_s3_bucket_replication_configuration" "replication" {
  for_each      = local.s3_input_folders

  depends_on    = [aws_s3_bucket_versioning.source_bucket]
  role          = aws_iam_role.s3-replication-prod[0].arn
  bucket        = aws_s3_bucket.source_bucket.id

  rule {
    id = each.value

    filter {
      prefix =  each.value
    }

    status = "Enabled"

    destination {
      bucket        = "arn:aws:s3:::${var.app}-dev"
      storage_class = "ONEZONE_IA"

      access_control_translation {
        owner       = "Destination"
      }
      account = var.dev_account_id
    }

    delete_marker_replication {
        status = "Enabled"
    }
  }
}

这不是循环并创建 10 个不同的规则,而是在每个 运行 上覆盖相同的规则,结果我只得到一个规则。

你应该使用 dynamic block:

resource "aws_s3_bucket_replication_configuration" "replication" {
  
  depends_on    = [aws_s3_bucket_versioning.source_bucket]
  role          = aws_iam_role.s3-replication-prod[0].arn
  bucket        = aws_s3_bucket.source_bucket.id

  dynamic "rule" {
    
    for_each      = toset(local.s3_input_folders)
    
    content {
    
        id = rule.value

        filter {
            prefix =  rule.value
        }

        status = "Enabled"

        destination {
        bucket        = "arn:aws:s3:::${var.app}-dev"
        storage_class = "ONEZONE_IA"

        access_control_translation {
            owner       = "Destination"
        }
        account = var.dev_account_id
        }

        delete_marker_replication {
            status = "Enabled"
        }
    }    
  }
}

谢谢,马辛。您提到的动态块构造可用于创建内容块,但它无法应用,因为 AWS 需要多个复制规则以按优先级区分。所以一些细微的修改实现了这一点:


locals {
  s3_input_folders_list_counter = tolist([
    for i in range(length(local.s3_input_folders)) : i
  ])
  s3_input_folders_count_map = zipmap(local.s3_input_folders_list_counter, tolist(local.s3_input_folders))
}

resource "aws_s3_bucket_replication_configuration" "replication" {
  depends_on    = [aws_s3_bucket_versioning.source_bucket]
  role          = aws_iam_role.s3-replication-prod[0].arn
  bucket        = aws_s3_bucket.source_bucket.id

   dynamic "rule" {
    
    for_each      = local.s3_input_folders_count_map
    
    content {
    
        id = rule.key
        priority = rule.key

        filter {
            prefix =  rule.value
        }

        status = "Enabled"

        destination {
        bucket        = "arn:aws:s3:::${var.app}-dev"
        storage_class = "ONEZONE_IA"

        access_control_translation {
            owner       = "Destination"
        }
        account = var.dev_account_id
        }

        delete_marker_replication {
            status = "Enabled"
        }
    }    
  }
}

创建如下规则:

+ rule {
          + id       = "0"
          + priority = 0
          + status   = "Enabled"

...
}
+ rule {
          + id       = "1"
          + priority = 1
          + status   = "Enabled"

...
}

等等...