如何将S3桶通知列表合并为桶名作为键的映射(Terraform)
Terraform 按桶名分组S3通知列表为映射结构
需要将多组S3桶通知的列表转换为以桶名为唯一键、对应值为该桶所有通知条目数组的映射结构,以此通过dynamic块遍历生成S3桶通知资源。
现有通知列表
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" } ] }
正确实现代码
通过先提取唯一桶名,再为每个桶名收集对应通知条目的方式,生成目标映射:
bucket_events = { for bucket_name in distinct(local.buckets_with_events[*].bucket) : bucket_name => [ for item in local.buckets_with_events : item if item.bucket == bucket_name ] }
代码说明
distinct(local.buckets_with_events[*].bucket):提取列表中所有唯一的桶名,避免重复处理- 外层for表达式:以每个唯一桶名为键,生成对应的条目数组
- 内层for表达式:遍历原始列表,筛选出当前桶名下的所有通知条目
资源生成示例(修正后)
使用生成的映射遍历创建S3桶通知资源,修正dynamic块中的变量引用错误:
resource "aws_s3_bucket_notification" "dynamic_s3_triggers" { for_each = local.bucket_events bucket = each.key dynamic "lambda_function" { for_each = lambda_function.value content { lambda_function_arn = aws_lambda_function.functions[lambda_function.value.function].arn events = lambda_function.value.events filter_prefix = lambda_function.value.filter_prefix filter_suffix = lambda_function.value.filter_suffix } } }
内容的提问来源于stack exchange,提问作者Robin Tanner
相关产品推荐
相关产品推荐

