使用模块动态块的 S3 复制 Terraform 错误

S3 Replication Terraform Error Using Module Dynamic Blocks

我正在尝试 运行 terraform 中的 s3 复制,这将是跨区域的。

我的部分主要s3.tf是

resource "aws_kms_key" "s3_replica-us-west-2-key" {
  description             = "S3 master key replica us-west-2"
  deletion_window_in_days = 30
  enable_key_rotation     = "true"
}

module "s3_replica" {
  source = "git@github.com:xxx"

  providers = {
    aws     = "aws.us-west-2"
  }

  name                  = "s3_replica"
  logging_bucket_prefix = "s3_replica"
  versioning            = var.versioning
  bucket_logging        = var.bucket_logging
  logging_bucket_name   = var.logging_bucket_name

  kms_key_id    = aws_kms_key.s3_replica-us-west-2-key.key_id
  sse_algorithm = var.sse_algorithm
}

module "s3" {
  source                = "git@github.com:xxxx"
  name                  = "s3"
  logging_bucket_prefix = "s3"
  versioning            = var.versioning
  bucket_logging        = var.bucket_logging
  logging_bucket_name   = var.logging_bucket_name

  kms_key_id    = aws_kms_key.s3.key_id
  sse_algorithm = var.sse_algorithm

 replication_configuration = {
    role = aws_iam_role.s3_replication.arn

      rules = [
        {
          prefix = ""
          status = "Enabled"

        destination = {
          bucket = module.s3_replica.bucket_arn
          replica_kms_key_id = aws_kms_alias.s3_replica-us-west-2-key.arn
          storage_class = "STANDARD_IA"
          }
        }
      ]  

      source_selection_criteria = {
          sse_kms_encrypted_objects = {
            enabled = true
          }
        }
  }
}  

我使用的模块中的复制配置块部分是:

dynamic "replication_configuration" {
    for_each = length(keys(var.replication_configuration)) == 0 ? [] : [var.replication_configuration]

    content {
      role = replication_configuration.value.role

      dynamic "rules" {
        for_each = replication_configuration.value.rules

        content {
          id       = lookup(replication_configuration.value.rules, "id", null)
          priority = lookup(replication_configuration.value.rules, "priority", null)
          prefix   = lookup(replication_configuration.value.rules, "prefix", null)
          status   = lookup(replication_configuration.value.rules, "status", null)

          dynamic "destination" {
            for_each = length(keys(lookup(rules.value, "destination", {}))) == 0 ? [] : [lookup(rules.value, "destination", {})]

            content {
              bucket             = lookup(destination.value, "bucket", null)
              storage_class      = lookup(destination.value, "storage_class", null)
              replica_kms_key_id = lookup(destination.value, "replica_kms_key_id", null)
              account_id         = lookup(destination.value, "account_id", null)
            }
          }

          dynamic "source_selection_criteria" {
            for_each = length(keys(lookup(rules.value, "source_selection_criteria", {}))) == 0 ? [] : [lookup(rules.value, "source_selection_criteria", {})]

            content {

              dynamic "sse_kms_encrypted_objects" {
                for_each = length(keys(lookup(source_selection_criteria.value, "sse_kms_encrypted_objects", {}))) == 0 ? [] : [lookup(source_selection_criteria.value, "sse_kms_encrypted_objects", {})]

                content {

                  enabled = sse_kms_encrypted_objects.value.enabled
                }
              }
            }
        }
      }
    }
    }
}
}

现在,当我 运行 terraform init 时...它起作用了。 但是当我 运行 terraform plan 我得到错误:

Error: Invalid function argument

  on .terraform/modules/s3/main.tf line 321, in resource "aws_s3_bucket" "s3_bucket":
 321:           id       = lookup(replication_configuration.value.rules, "id", null)
    |----------------
    | replication_configuration.value.rules is tuple with 1 element

Invalid value for "inputMap" parameter: lookup() requires a map as the first
argument.


Error: Invalid function argument

  on .terraform/modules/s3/main.tf line 322, in resource "aws_s3_bucket" "s3_bucket":
 322:           priority = lookup(replication_configuration.value.rules, "priority", null)
    |----------------
    | replication_configuration.value.rules is tuple with 1 element

Invalid value for "inputMap" parameter: lookup() requires a map as the first
argument.


Error: Invalid function argument

  on .terraform/modules/s3/main.tf line 323, in resource "aws_s3_bucket" "s3_bucket":
 323:           prefix   = lookup(replication_configuration.value.rules, "prefix", null)
    |----------------
    | replication_configuration.value.rules is tuple with 1 element

Invalid value for "inputMap" parameter: lookup() requires a map as the first
argument.


Error: Invalid function argument

  on .terraform/modules/s3/main.tf line 324, in resource "aws_s3_bucket" "s3_bucket":
 324:           status   = lookup(replication_configuration.value.rules, "status", null)
    |----------------
    | replication_configuration.value.rules is tuple with 1 element

Invalid value for "inputMap" parameter: lookup() requires a map as the first
argument.

我认为你必须 转换 你的 rules 到地图,以便它适合 for_each:

      dynamic "rules" {
        for_each = { for idx, val in replication_configuration.value.rules: idx => val}

        content {
          id       = lookup(rules.value, "id", null)
          priority = lookup(rules.value, "priority", null)
          prefix   = lookup(rules.value, "prefix", null)
          status   = lookup(rules.value, "status", null)