如何将映射中的内部元素列表合并到具有集合类型值的映射中

问题描述 投票:0回答:2

您好,我正在尝试将一组定义如下的存储桶通知转换为映射:序列结构,以便我可以使用存储桶通知中的动态块迭代该序列。

buckets_with_events = [
  {
    "bucket" = "bucket1"
    "events" = [
      "s3:ObjectCreated:*",
    ]
    "filter_prefix" = tostring(null)
    "filter_suffix" = ".xml"
    "function" = "lambda1"
  },
  {
    "bucket" = "bucket1"
    "events" = [
      "s3:ObjectCreated:*",
    ]
    "filter_prefix" = tostring(null)
    "filter_suffix" = ".csv"
    "function" = "lambda1"
  },
  {
    "bucket" = "bucket2"
    "events" = [
      "s3:ObjectCreated:*",
    ]
    "filter_prefix" = tostring(null)
    "filter_suffix" = ".csv"
    "function" = "lambda1"
  }]

我需要将存储桶作为唯一键,并将所有事件合并为该键下的单个序列。我一直在尝试以下操作,但我似乎无法正确地将元组/集合/序列分配给地图键。

  bucket_events = flatten([
    for parent_obj in local.buckets_with_events:
        parent_obj.bucket => [
          for obj in local.buckets_with_events:
            {events = obj.events
             filter_suffix = obj.filter_suffix} if parent_obj.bucket == obj.bucket
    ]
  ])

我想要实现的输出如下:

bucket_events = {
  "bucket1" = [{
    
    "events" = [
      "s3:ObjectCreated:*",
    ]
    "filter_prefix" = tostring(null)
    "filter_suffix" = ".xml"
    "function" = "lambda1"
  },
  {
    "events" = [
      "s3:ObjectCreated:*",
    ]
    "filter_prefix" = tostring(null)
    "filter_suffix" = ".csv"
    "function" = "lambda1"
  }]
  "bucket2" = [{
    "events" = [
      "s3:ObjectCreated:*",
    ]
    "filter_prefix" = tostring(null)
    "filter_suffix" = ".csv"
    "function" = "lambda1"
  }]

通过这种方式,我可以使用 for_each 和动态轻松生成所需的所有存储桶通知,如下所示 --

resource "aws_s3_bucket_notification" "dynamic_s3_triggers" {
  for_each = var.bucket_events
  bucket = each.key
  dynamic "lambda_function" {

      content {
      lambda_function_arn = aws_lambda_function.functions[lambda_function.function].function].arn
      ...
       }
    }
}
dynamic terraform nested-loops local-variables
2个回答
0
投票

(可能与这个重复)

以下代码实现了您的要求:

  map_bucket_all_events = {
    for bucket in local.buckets_with_events : bucket.bucket => {
      events        = bucket.events
      filter_prefix = bucket.filter_prefix
      filter_suffix = bucket.filter_suffix
      function      = bucket.function
    }...
  }

“魔法”是使用省略号运算符完成的,该运算符用于根据键执行某种“分组依据”操作(此处的文档)。

我已经使用

terraform console
在本地进行了测试,这就是我得到的输出:

{
  "bucket1" = [
    {
      "events" = [
        "s3:ObjectCreated:*",
      ]
      "filter_prefix" = tostring(null)
      "filter_suffix" = ".xml"
      "function" = "lambda1"
    },
    {
      "events" = [
        "s3:ObjectCreated:*",
      ]
      "filter_prefix" = tostring(null)
      "filter_suffix" = ".csv"
      "function" = "lambda1"
    },
  ]
  "bucket2" = [
    {
      "events" = [
        "s3:ObjectCreated:*",
      ]
      "filter_prefix" = tostring(null)
      "filter_suffix" = ".csv"
      "function" = "lambda1"
    },
  ]
}

0
投票

考虑以下代码:

locals {
  buckets_with_events = [
    {
      "bucket" = "bucket1"
      "events" = [
        "s3:ObjectCreated:*",
      ]
      "filter_prefix" = tostring(null)
      "filter_suffix" = ".xml"
      "function"      = "lambda1"
    },
    {
      "bucket" = "bucket1"
      "events" = [
        "s3:ObjectCreated:*",
      ]
      "filter_prefix" = tostring(null)
      "filter_suffix" = ".csv"
      "function"      = "lambda1"
    },
    {
      "bucket" = "bucket2"
      "events" = [
        "s3:ObjectCreated:*",
      ]
      "filter_prefix" = tostring(null)
      "filter_suffix" = ".csv"
      "function"      = "lambda1"
  }]

  distinct_buckets = distinct([
    for be in local.buckets_with_events : be.bucket
  ])

  buckets_map = {
    for bucket_event in local.distinct_buckets :
    bucket_event => [
      for be in local.buckets_with_events :
      {
        events        = be.events
        filter_prefix = be.filter_prefix
        filter_suffix = be.filter_suffix
        function      = be.function
      }
      if be.bucket == bucket_event
    ]
  }
}

output "buckets_map" {
  value = local.buckets_map
}

跑步

terraform plan

Changes to Outputs:
  + buckets_map = {
      + bucket1 = [
          + {
              + events        = [
                  + "s3:ObjectCreated:*",
                ]
              + filter_prefix = null
              + filter_suffix = ".xml"
              + function      = "lambda1"
            },
          + {
              + events        = [
                  + "s3:ObjectCreated:*",
                ]
              + filter_prefix = null
              + filter_suffix = ".csv"
              + function      = "lambda1"
            },
        ]
      + bucket2 = [
          + {
              + events        = [
                  + "s3:ObjectCreated:*",
                ]
              + filter_prefix = null
              + filter_suffix = ".csv"
              + function      = "lambda1"
            },
        ]
    }
© www.soinside.com 2019 - 2024. All rights reserved.