介绍
维护者需要一个共享位置来保存正在使用的资源栈的资源映射。你将本地状态迁移到独立且启用版本管理的 S3 后端,同时保留现有报告,然后观察状态历史和后端的独立生命周期。
你应已了解 Terraform 状态、导入、已保存的计划和 S3 对象版本。本实验的所有资源均在此全新环境中准备就绪;无需之前的状态或个人 AWS 账户。
与认证考试的关联
| 认证 | 考试任务 | 实践内容 |
|---|---|---|
| CloudOps Engineer – Associate (SOA-C03) | 任务 3.1,技能 3.1.6 | Terraform 基础实践:通过经过审查的配置和状态变更维护基础设施,同时保留正在使用的资源。 |
实验概览

明确本地状态与后端的边界
在这一步中,识别业务存储桶以及用于保存状态的独立目标位置。提供的报告根目录已管理 migration-daily-reports;其本地状态独立于财务参考存储。启用版本管理的 maintenance-team-state 存储桶由平台团队准备,因此在此根目录开始使用它之前就已存在。
cd /home/labex/project/state-migration
terraform state list
terraform state show aws_s3_bucket.reports
确认远端存储桶 ID 为 migration-daily-reports。后端负责保存资源映射;它与创建和读取 AWS 资源的 Provider 不同。本环境分别准备了 Provider 和后端的连接设置。
更改状态存储位置之前,先保存一份私有本地备份。重定向符(>)将状态 JSON 写入文件;不要将状态或计划提交到公共源代码仓库:
terraform state pull > local-before-migration.json
chmod 600 local-before-migration.json
检查后端的版本管理及最初为空的对象清单:
aws s3api \
get-bucket-versioning \
--bucket maintenance-team-state
预期看到 Status: Enabled。
aws s3api \
list-objects-v2 \
--bucket maintenance-team-state
此时应尚无状态对象。选择空目标位置很重要:迁移到已属于另一个环境的键,可能覆盖其管理记录。保持 migration-finance-reference 不变。
将现有映射迁移到指定的 S3 键
在这一步中,配置远端后端,并将现有本地资源映射复制到其空目标位置。键是后端存储桶内状态对象的名称;应为某一个特定环境选择该键。
编写一个部分配置的 S3 后端声明。连接设置单独提供,下一个文件则指定你选择的存储桶和键:
cat > backend.tf <<'HCL'
terraform {
backend "s3" {}
}
HCL
创建此环境专用的后端配置。use_lockfile = true 为后续写入者启用 Terraform 原生 S3 锁文件:
cat > reports.s3.tfbackend <<'HCL'
bucket = "maintenance-team-state"
key = "reports/production.tfstate"
region = "us-east-1"
use_lockfile = true
HCL
-migrate-state 要求 Terraform 将现有映射迁移到新后端。Terraform 会询问是否复制现有状态;printf 管道提供回答 yes。仅在确认本实验的目标键原本为空后,才能运行:
printf 'yes\n' | terraform init \
-backend-config=backend-connection.hcl \
-backend-config=reports.s3.tfbackend \
-migrate-state
预期 S3 后端配置成功并完成初始化。不要用迁移来切换到已经存在的环境:选择现有状态是另一种操作,将在本课程后续内容中介绍。
从新位置检查映射:
terraform state show aws_s3_bucket.reports
资源 ID 必须仍为 migration-daily-reports。确认 S3 现在包含实际的状态对象:
aws s3api \
head-object \
--bucket maintenance-team-state \
--key reports/production.tfstate
ETag 和 VersionId 显示状态对象已存储。仅有这些元数据还不够:后台检查也会读取其资源映射,并比较现有报告的标识和字节。
terraform plan
预期看到 No changes。迁移状态不应重新创建业务存储桶。
观察远端状态的新版本
在这一步中,执行一项经过审查的配置更新,并观察由此产生的状态历史。版本管理保留较早的状态对象;本实验观察历史,不涉及恢复损坏的状态。
添加一个修订标签,同时保持存储桶名称、所有者和销毁设置不变:
cat > main.tf <<'HCL'
resource "aws_s3_bucket" "reports" {
bucket = "migration-daily-reports"
force_destroy = false
tags = { Owner = "reporting", Revision = "two" }
}
HCL
审查已保存的计划:
terraform plan -out=revision.tfplan
预期看到 0 to add, 1 to change, 0 to destroy。仅应用这项就地更新:
terraform apply revision.tfplan
检查后端对象的版本:
aws s3api \
list-object-versions \
--bucket maintenance-team-state \
--prefix reports/production.tfstate
迁移和更新后,应至少存在两个状态版本。它们描述管理历史,与另一个存储桶中业务报告的版本不同。
aws s3 \
cp s3://migration-daily-reports/report.txt -
报告内容仍为 Daily sales: 120 orders。AWS View 将业务、财务参考和后端显示为独立的存储桶。状态文件可能包含敏感值;仅检查本练习所需的元数据。
terraform plan
预期看到 No changes。在开始单独的清理阶段之前,先验证此正常工作的状态。
删除业务资源并保留后端
在这一步中,在功能和数据保留检查通过之后,停用这个一次性业务资源栈。平台团队的后端和独立的财务参考存储不在此资源栈的删除范围内。
force_destroy = false 防止 Terraform 静默清空启用版本管理的报告存储桶。删除本实验报告之前,先明确识别原始报告版本。命令替换保存其 ID;显示这个非敏感标识:
VERSION_ID=$(aws s3api \
head-object \
--bucket migration-daily-reports \
--key report.txt \
--query VersionId \
--output text)
echo "$VERSION_ID"
删除这个确切的一次性报告版本,然后销毁业务资源。只有在上一步保留检查完成之后,这些命令才会有意终止报告的可用性:
aws s3api \
delete-object \
--bucket migration-daily-reports \
--key report.txt \
--version-id "$VERSION_ID"
terraform destroy -auto-approve
-auto-approve 跳过确认提示;此处仅将它用于你刚审查过的单个一次性业务存储桶。预期看到 1 destroyed。
确认其管理记录仍存在于后端:
aws s3api \
head-object \
--bucket maintenance-team-state \
--key reports/production.tfstate
后端仍然保留,现在保存的状态中已没有受管理的业务资源。财务参考报告必须仍然可用。销毁资源栈不会删除其后端使用的存储。为后端所有者保持后端完整不变;不要再次运行普通 apply,否则会重新创建配置所期望的业务存储桶。
有关后端配置和原生锁文件的说明,请参阅 S3 后端文档。
总结
你区分了 Provider 和后端的职责,备份现有映射并将其迁移到 S3,观察了状态版本,并在删除业务资源栈时保留了归属独立的后端。



