You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Terraform仅上传指定文件至S3 Bucket?

问题描述

我的目录结构如下:

--scripts_folder
  --code1_folder
    --abc.txt
  --code2_folder
    --def.csv
  --abcd_tst.yaml
  --def_tst.json
  --abcd_dev.yaml
  --def_dev.json

我原本使用以下Terraform代码将scripts_folder下所有文件夹和文件上传至S3 Bucket:

main.tf

resource "aws_s3_bucket_object" "data_scripts" {
  for_each = fileset("./scripts_folder/", "**")
  bucket   = module.s3_bucket.name
  key      = each.value
  source   = "./scripts_folder/${each.value}"
  etag     = filemd5("./scripts_folder/${each.value}")
}

但当前需求是仅上传指定对象至S3,具体如下:

--scripts_folder
  --code1_folder
    --abc.txt
  --code2_folder
    --def.csv
  --abcd_tst.yaml
  --def_tst.json

请问如何修改Terraform配置以实现该需求?

解决方案

可以通过以下几种方式实现精准上传指定文件:

方法一:使用fileset组合匹配规则

直接在fileset中指定需要包含的路径和文件模式,用大括号分组多个匹配规则:

resource "aws_s3_bucket_object" "data_scripts" {
  for_each = fileset("./scripts_folder/", "{code1_folder/**,code2_folder/**,abcd_tst.yaml,def_tst.json}")
  bucket   = module.s3_bucket.name
  key      = each.value
  source   = "./scripts_folder/${each.value}"
  etag     = filemd5("./scripts_folder/${each.value}")
}

其中code1_folder/**会匹配该文件夹下所有层级的文件,后面的文件名则精准匹配指定文件,用逗号分隔不同规则即可。

方法二:显式定义目标文件列表

如果需要更直观的控制权,可以直接定义包含所有目标文件的集合,再遍历上传:

locals {
  target_files = [
    "code1_folder/abc.txt",
    "code2_folder/def.csv",
    "abcd_tst.yaml",
    "def_tst.json"
  ]
}

resource "aws_s3_bucket_object" "data_scripts" {
  for_each = toset(local.target_files)
  bucket   = module.s3_bucket.name
  key      = each.value
  source   = "./scripts_folder/${each.value}"
  etag     = filemd5("./scripts_folder/${each.value}")
}

这种方式适合文件数量不多的场景,后续调整上传范围只需修改target_files列表即可。

方法三:排除不需要的文件

如果仅需排除少数文件(比如这里的*_dev.*后缀文件),可以用集合差集过滤:

locals {
  all_files = fileset("./scripts_folder/", "**")
  exclude_files = fileset("./scripts_folder/", "*_dev.*")
  target_files = setdifference(local.all_files, local.exclude_files)
}

resource "aws_s3_bucket_object" "data_scripts" {
  for_each = local.target_files
  bucket   = module.s3_bucket.name
  key      = each.value
  source   = "./scripts_folder/${each.value}"
  etag     = filemd5("./scripts_folder/${each.value}")
}

这种方式无需逐个列出需要保留的文件,适合需排除特定模式文件的场景。

内容的提问来源于stack exchange,提问作者Sayon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 00:35:29