Terraform:local_file生成文件无法上传S3,如何配置依赖?
问题分析
你遇到的核心问题是:Terraform的fileset函数在执行计划阶段就会扫描目录生成文件列表,这时候local_file.app_config还没创建出config.json,所以这个文件根本没被纳入aws_s3_object.upload_object的for_each集合里。哪怕你加了depends_on,也只是让S3上传操作等文件生成后再执行,但上传的文件列表在计划阶段就已经固定了,自然不会包含后生成的config.json。
解决方案
最简单可靠的方式是把config.json的上传单独拆成一个aws_s3_object资源,和批量遍历的资源分开,这样可以明确让它依赖local_file.app_config,确保文件生成后再执行上传。
修改后的代码如下:
# 生成config.json文件 resource "local_file" "app_config" { filename = "../frontend/build/config.json" content = jsonencode(local.config) } # 批量上传其他文件 resource "aws_s3_object" "upload_other_objects" { for_each = fileset(local.build_dir, "**") bucket = aws_s3_bucket.bucket.id key = each.value source = "${local.build_dir}${each.value}" content_type = lookup(local.content_types, element(split(".", each.value), length(split(".", each.value)) - 1), "text/plain") etag = filemd5("${local.build_dir}${each.value}") } # 单独上传config.json,明确依赖文件生成操作 resource "aws_s3_object" "upload_config" { bucket = aws_s3_bucket.bucket.id key = "config.json" # 对应S3里的键,可根据实际需求调整 source = local_file.app_config.filename content_type = "application/json" etag = filemd5(local_file.app_config.filename) depends_on = [local_file.app_config] }
如果不想拆分资源,也可以通过合并文件列表的方式处理,但需要保证路径一致性:
resource "local_file" "app_config" { filename = "../frontend/build/config.json" content = jsonencode(local.config) } resource "aws_s3_object" "upload_object" { # 合并fileset结果和config.json的相对路径,去重避免重复上传 for_each = distinct(concat(fileset(local.build_dir, "**"), ["config.json"])) bucket = aws_s3_bucket.bucket.id key = each.value source = "${local.build_dir}${each.value}" content_type = lookup(local.content_types, element(split(".", each.value), length(split(".", each.value)) - 1), "text/plain") etag = filemd5("${local.build_dir}${each.value}") depends_on = [local_file.app_config] }
这种方式是手动把config.json加入到for_each的集合里,即使计划阶段文件不存在,Terraform也会在执行阶段等待文件生成后再处理这个条目。注意要保证local.build_dir的路径和local_file.app_config.filename的父目录一致,比如local.build_dir设为"../frontend/build/",这样"${local.build_dir}config.json"就是正确的文件路径。
关键注意点
- Terraform的大部分函数(比如
fileset、filemd5)都是计划阶段求值,如果依赖执行阶段才会创建的文件,必须通过资源依赖或者显式指定条目来处理。 - 单独拆分资源的方式逻辑更清晰,也更容易排查问题,推荐优先使用。
内容的提问来源于stack exchange,提问作者pTrik
相关产品推荐
相关产品推荐

