Terraform中通过for_each获取S3/Glue属性配置Kinesis Firehose
解决Kinesis Firehose引用批量创建的S3 Bucket和Glue Table的问题
核心思路:通过一致的for_each键关联资源
批量创建资源时,只要确保S3 Bucket、Glue Table、Firehose三者的for_each使用相同的键集合,就能通过键直接索引到对应的资源属性。
具体实现步骤
1. 定义变量结构(示例)
假设你的my_bucket_map变量结构如下,每个键对应一组Bucket和Glue Table的配置:
variable "my_bucket_map" { type = map(object({ bucket_name = string glue_database = string table_name_suffix = string # 用于生成Glue表名的后缀 # 其他Glue表所需参数,比如字段定义、存储前缀等 })) }
2. 批量创建S3 Bucket
用var.my_bucket_map作为for_each的数据源,确保每个键对应一个Bucket:
resource "aws_s3_bucket" "my_buckets" { for_each = var.my_bucket_map bucket = each.value.bucket_name # 其他Bucket配置,比如版本控制、加密等 }
3. 嵌套创建Glue Catalog Table
同样使用var.my_bucket_map作为for_each数据源,保持键和Bucket一致,同时关联对应的Bucket存储路径:
resource "aws_glue_catalog_table" "my_tables" { for_each = var.my_bucket_map name = "${each.value.bucket_name}_${each.value.table_name_suffix}" database_name = each.value.glue_database storage_descriptor { location = "s3://${aws_s3_bucket.my_buckets[each.key].bucket}/data/" # 字段定义、输入输出格式等其他配置 } }
4. 创建依赖的Kinesis Firehose交付流
继续使用var.my_bucket_map作为for_each数据源,通过each.key直接索引对应的Bucket ARN和Glue表名:
resource "aws_kinesis_firehose_delivery_stream" "my_streams" { for_each = var.my_bucket_map name = "${each.value.bucket_name}_firehose" # S3目标配置,引用对应Bucket的ARN s3_configuration { role_arn = aws_iam_role.firehose_exec_role.arn bucket_arn = aws_s3_bucket.my_buckets[each.key].arn prefix = "raw/" error_output_prefix = "errors/" } # Glue数据目录配置,引用对应Table的名称 glue_configuration { database_name = each.value.glue_database table_name = aws_glue_catalog_table.my_tables[each.key].name } # 其他Firehose配置,比如源类型(Kinesis Stream/Direct Put)等 }
处理一对多场景(一个Bucket对应多个Glue Table)
如果你的需求是一个Bucket下创建多个Glue Table,再对应多个Firehose,可以先通过locals将结构扁平化为一对一的键值对:
# 扁平化为Bucket-Table的配对集合 locals { bucket_table_pairs = flatten([ for bucket_key, bucket_data in var.my_bucket_map : [ for table_suffix in bucket_data.table_suffixes : { unique_key = "${bucket_key}-${table_suffix}" bucket_key = bucket_key table_name = "${bucket_data.bucket_name}_${table_suffix}" database_name = bucket_data.glue_database } ] ]) } # 基于扁平后的集合创建Firehose resource "aws_kinesis_firehose_delivery_stream" "my_streams" { for_each = { for pair in local.bucket_table_pairs : pair.unique_key => pair } name = "${each.value.table_name}_firehose" s3_configuration { role_arn = aws_iam_role.firehose_exec_role.arn bucket_arn = aws_s3_bucket.my_buckets[each.value.bucket_key].arn # 其他S3配置 } glue_configuration { database_name = each.value.database_name table_name = aws_glue_catalog_table.my_tables[each.value.unique_key].name } }
关键注意事项
- 保持键的一致性:所有关联资源的
for_each必须使用相同的键(或可映射的键),否则无法准确索引到对应的资源属性。 - 资源引用语法:通过
资源类型.资源名称[键].属性的方式获取批量创建资源的属性,比如aws_s3_bucket.my_buckets["bucket_key_1"].arn。 - 避免硬编码:不要直接写死Bucket名称或表名,始终通过资源引用获取,确保Terraform能正确处理依赖关系。
内容的提问来源于stack exchange,提问作者krishna hegde
相关产品推荐
相关产品推荐

