Terraform上传S3对象时旧文件被删除,如何保留历史文件仅新增资源
问题根因
Terraform 中每个aws_s3_bucket_object资源实例对应S3存储桶内的一个唯一对象,你修改同一个资源实例的source等参数时,Terraform会默认执行资源更新/替换操作,本质是修改该实例对应的S3对象内容,所以旧文件会被覆盖删除,这是Terraform资源声明的默认逻辑,并非状态管理异常。
另外你的配置中key参数固定为folder1/,相当于把两个不同的文件都上传为S3中同一个名为folder1/的对象,即使不用Terraform,直接调用S3 API重复上传同一个key也会覆盖旧内容。
解决方案
方案1:新增独立资源实例(适合少量文件上传)
需要保留的每个文件对应一个独立的aws_s3_bucket_object资源,且每个资源的key参数保持唯一,不要复用同一个资源实例修改参数。示例配置如下:
# 保留原有File1的资源声明不要修改 resource "aws_s3_bucket_object" "s3_upload_file1" { bucket = "bucket1" key = "folder1/File1.txt" source = "File1.txt" kms_key_id = "" } # 新增File2的独立资源声明 resource "aws_s3_bucket_object" "s3_upload_file2" { bucket = "bucket1" key = "folder1/File2.txt" source = "File2.txt" kms_key_id = "" }
执行apply时只会新增第二个对象,不会修改/删除第一个文件。
方案2:批量声明资源(适合多文件批量上传)
如果需要频繁新增上传文件,可通过for_each批量生成资源,后续新增文件只需在文件列表中添加条目即可,不会影响已上传的文件。示例配置如下:
# 定义需要上传的文件列表,后续新增文件直接往列表里加即可 variable "upload_files" { type = set(string) default = ["File1.txt", "File2.txt"] } resource "aws_s3_bucket_object" "batch_upload" { for_each = var.upload_files bucket = "bucket1" key = "folder1/${each.value}" source = each.value kms_key_id = "" }
方案3:将旧文件脱离Terraform管理
如果你不需要Terraform再管控之前上传的File1,可执行以下命令将对应资源从Terraform状态中移除,后续操作不会再删除该文件:
terraform state rm aws_s3_bucket_object.s3_automation_upload1
内容的提问来源于stack exchange,提问作者Balaji
相关产品推荐
相关产品推荐

