您好,我正在尝试将一组定义如下的存储桶通知转换为映射:序列结构,以便我可以使用存储桶通知中的动态块迭代该序列。
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
...
}
}
}
(可能与这个重复)
以下代码实现了您的要求:
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"
},
]
}
考虑以下代码:
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"
},
]
}