Terraform 0.13.7条件for_each下游依赖及资源数据源切换问题
问题根因
你遇到的报错是因为当create_staging_bucket为false时,aws_s3_bucket.staging_bucket的for_each会过滤掉对应key,直接在下游硬编码引用aws_s3_bucket.staging_bucket[each.key]必然会出现索引不存在的错误。
解决方案
可以通过条件数据源+统一属性映射的方式实现resource和data的动态切换,无需修改下游依赖逻辑,完全兼容Terraform 0.13.7版本:
步骤1:新增条件查询的S3桶数据源
新增aws_s3_bucket数据源,仅当不需要创建桶时,查询已存在的桶信息:
data "aws_s3_bucket" "existing_staging_bucket" { for_each = {for k, v in var.snowpipes : k => v if v.create_staging_bucket == false} bucket = lower(each.value.staging_bucket.url) }
步骤2:构造统一的桶属性映射
通过局部值将创建的桶、查询到的桶的属性合并为同一个Map,下游直接引用该映射即可,不需要区分桶的来源:
locals { # 合并两类桶的ID映射,同一个key只会出现在其中一个集合中,无合并冲突 staging_bucket_id_map = merge( {for k, v in aws_s3_bucket.staging_bucket : k => v.id}, {for k, v in data.aws_s3_bucket.existing_staging_bucket : k => v.id} ) # 如果需要其他统一属性(比如ARN)也可以按同样逻辑构造对应的映射 staging_bucket_arn_map = merge( {for k, v in aws_s3_bucket.staging_bucket : k => v.arn}, {for k, v in data.aws_s3_bucket.existing_staging_bucket : k => v.arn} ) }
步骤3:修改下游通知资源的引用逻辑
直接从统一映射中取桶ID即可,无需再做条件判断:
resource "aws_s3_bucket_notification" "bucket_notification" { for_each = var.snowpipes bucket = local.staging_bucket_id_map[each.key] # 其余配置保持不变 ... }
可选优化
如果你的变量中已经明确填写了桶ARN/名称等信息,且可以确保信息准确,也可以省略数据源查询,直接从变量中取值构造local映射,减少一次API查询:
locals { staging_bucket_id_map = merge( {for k, v in aws_s3_bucket.staging_bucket : k => v.id}, {for k, v in var.snowpipes : k => lower(v.staging_bucket.url) if v.create_staging_bucket == false} ) }
内容的提问来源于stack exchange,提问作者Tony
相关产品推荐
相关产品推荐

