介绍
新版报告不应让团队失去读取早期数据的能力。你将配置版本管理,发布两版报告,区分历史读取与当前读取,然后有意清理这个一次性存储。
运用上一个实验中的变量、对象引用和独立根目录知识。此全新环境仅提供工具、provider 访问配置和一份无关的参考报告。
与认证考试的关联
| 认证 | 考试任务 | 实践内容 |
|---|---|---|
| Cloud Practitioner (CLF-C02) | 任务 3.1 | 使用可重复的基础设施定义和运维资源查询。 |
| Developer – Associate (DVA-C02) | 任务 3.3,技能 3.3.4 | 部署基础设施定义的基础实践。 |
| DevOps Engineer – Professional (DOP-C02) | 任务 2.1 | 通过 IaC 定义管理资源的基础实践。 |
| Solutions Architect – Associate (SAA-C03) | 任务 1.3 | 在有意清理之前保留和读取 S3 历史数据的基础实践。 |

发布第一个版本
在这一步中,你将在发布第一版报告之前,使用 Terraform 管理存储桶的版本管理配置。
S3 对象版本是保留的数据副本,每份都有版本 ID。它们不同于 HCL 的 Git 修订,也不同于 Terraform 的 provider 锁定文件。Terraform 可以配置版本管理;此后数据更新时,S3 会保留对象版本。仅计划没有变更,不能证明历史数据可读。
进入已准备好的根目录并编写存储定义:
cd /home/labex/project/report-history
cat > main.tf <<'EOF'
variable "report" { type = string }
resource "aws_s3_bucket" "reports" {
bucket = "terraform-history-reports"
}
resource "aws_s3_bucket_versioning" "reports" {
bucket = aws_s3_bucket.reports.id
versioning_configuration {
status = "Enabled"
}
}
resource "aws_s3_object" "report" {
bucket = aws_s3_bucket.reports.id
key = "reports/current.csv"
content = var.report
content_type = "text/csv"
depends_on = [aws_s3_bucket_versioning.reports]
}
EOF
现在有三个资源:存储桶、其版本管理设置,以及一个对象。对象已通过 ID 引用依赖存储桶。显式 depends_on 增加了仅从该引用无法推断的顺序:必须在首次上传前启用版本管理。
写入第一版报告的输入并初始化:
cat > release1.tfvars <<'EOF'
report = "orders,12\n"
EOF
terraform init
terraform validate
terraform plan -var-file=release1.tfvars
预期新增三个资源。应用配置并输入 yes:
terraform apply -var-file=release1.tfvars
查询实际设置和第一个版本:
aws s3api \
get-bucket-versioning \
--bucket terraform-history-reports
aws s3api \
list-object-versions \
--bucket terraform-history-reports \
--query 'Versions[].{Key:Key,VersionId:VersionId,Current:IsLatest}'
状态为 Enabled。报告具有非 null 的版本 ID,且 Current: true。AWS View 显示当前可读的对象;使用版本查询检查历史。

更新报告并读取历史
在这一步中,你将发布不同的字节,显式读取旧版本,并证明读取历史不会改变当前报告。
创建第二个输入文件。保留两个文件便于比较预期的数据版本;这些文件本身并非存储中的历史记录。
cat > release2.tfvars <<'EOF'
report = "orders,25\n"
EOF
terraform plan -var-file=release2.tfvars -out=update.tfplan
terraform show update.tfplan
预期更新一个对象,不替换存储桶。-out 保存的计划产物包含选定的输入值。应用这份已审查的产物;此命令不会请求确认,因为你已选择保存的计划:
terraform apply update.tfplan
再次列出实际版本:
aws s3api \
list-object-versions \
--bucket terraform-history-reports \
--query 'Versions[].{Key:Key,VersionId:VersionId,Current:IsLatest}'
旧条目与当前条目具有不同的版本 ID。选择较旧报告的 ID 并显示它。查询按报告键和 IsLatest == false 筛选;[0] 选择本实验两个版本的历史中第一个匹配的旧条目。
OLD_VERSION=$(aws s3api \
list-object-versions \
--bucket terraform-history-reports \
--query 'Versions[?Key==`reports/current.csv` && IsLatest==`false`].VersionId | [0]' \
--output text)
echo "$OLD_VERSION"
CURRENT_VERSION=$(aws s3api \
head-object \
--bucket terraform-history-reports \
--key reports/current.csv \
--query VersionId \
--output text)
echo "$CURRENT_VERSION"
按 ID 下载旧版本,然后不指定版本 ID 下载当前版本:
aws s3api \
get-object \
--bucket terraform-history-reports \
--key reports/current.csv \
--version-id "$OLD_VERSION" \
old-report.csv
cat old-report.csv
aws s3api \
get-object \
--bucket terraform-history-reports \
--key reports/current.csv \
current-report.csv
cat current-report.csv
预期旧文件中为 orders,12,当前文件中为 orders,25。指定版本的 GET 读取一个现有版本;它不会把该版本复制到当前对象上。再次查询当前 ID,并将其与显示的 CURRENT_VERSION 比较:
aws s3api \
head-object \
--bucket terraform-history-reports \
--key reports/current.csv \
--query VersionId \
--output text
ID 保持不变。删除任何版本之前,先完成本步骤检查。检查会读取实际的旧版和当前字节,并保留两者。有关对象键、版本与删除标记之间的区别,请参阅 S3 版本管理。
有意删除自有历史版本
在这一步中,你将先列出并删除一次性报告存储桶中的全部版本,再移除 Terraform 配置中定义的资源。
销毁基础设施与决定丢弃报告历史是不同的操作。非空且启用版本管理的存储桶通常无法删除。不指定版本 ID 删除当前对象,可能创建删除标记,它会隐藏当前对象,但旧版本仍保留。此处,在上一步证明历史已保留之后,你将按 ID 显式删除清单中的版本。
根据原生版本列表创建删除请求。本实验仅有少量报告版本,且没有已有删除标记;列出的每个版本都属于你的存储桶。--query 将各条目转换为 delete-objects 接受的 Key/VersionId 字段。
aws s3api \
list-object-versions \
--bucket terraform-history-reports \
--query '{Objects: Versions[].{Key:Key,VersionId:VersionId}}' \
> owned-versions.json
cat owned-versions.json
审查文件,确认其中只包含来自 terraform-history-reports 的版本。然后删除这些确切版本。file:// 要求 AWS CLI 从本地文件读取 JSON 请求。
aws s3api \
delete-objects \
--bucket terraform-history-reports \
--delete file://owned-versions.json
aws s3api \
list-object-versions \
--bucket terraform-history-reports
成功返回的列表中没有 Versions 或 DeleteMarkers 条目。现在销毁此根目录的资源,并输入 yes:
terraform destroy -var-file=release2.tfvars
Terraform 先刷新状态,可能发现对象已删除。随后它会移除剩余的版本管理配置和空存储桶。最后检查映射和保留的参考报告:
terraform state list
aws s3api \
list-buckets \
--query 'Buckets[].Name'
aws s3api \
head-object \
--bucket team-reference-reports \
--key keep.txt \
--query ContentLength
状态列表为空,只剩下团队参考存储桶。不要在必须保留历史的存储上使用这套丢弃数据的流程。
总结
你区分了配置变更与数据版本,在上传前启用了版本管理,读取了不同的旧版和当前报告字节而未覆盖当前版本,并且仅对自有版本显式列出清单后予以删除。



