介绍
两名维护者各有同一环境的工作副本。你将观察实际写入共享状态的进程、因其原生锁而被拒绝的竞争计划,以及正常释放锁后从另一个目录成功执行的操作。
你需要了解远端 S3 状态和常规 Terraform 计划及应用操作。此全新环境提供两个已初始化的工作副本、一项受控的定时变更、报告存储和财务参考报告;无需之前的虚拟机或个人 AWS 账户。
与认证考试的关联
| 认证 | 考试任务 | 实践内容 |
|---|---|---|
| CloudOps Engineer – Associate (SOA-C03) | 任务 3.1,技能 3.1.6 | Terraform 基础实践:通过经过审查的配置和状态变更维护基础设施,同时保留正在使用的资源。 |
实验概览

识别同一环境的两个副本
在这一步中,确认两个工作目录有意管理同一个环境。它们并非独立的 dev 和 preview 部署:两个后端配置均选择 coordination-team-state 中的 reports/shared.tfstate。
cd /home/labex/project/shared-state-operators
cat operator-a/shared.s3.tfbackend
cat operator-b/shared.s3.tfbackend
两者均使用 use_lockfile = true。写入进程操作期间,Terraform 会在此状态旁创建一个原生 S3 锁对象,以防另一个写入进程依据存在冲突的快照进行操作。
terraform -chdir=operator-a state show aws_s3_bucket.reports
terraform -chdir=operator-b state show aws_s3_bucket.reports
两者均标识 coordinated-daily-reports。读取其中的实际报告,并保持财务参考报告不变:
aws s3 \
cp s3://coordinated-daily-reports/report.txt -
预期看到 Daily sales: 120 orders。检查提供的受控变更:
cat operator-a/pending-change.tf
仅为本练习,一个 terraform_data 资源会通过 local-exec 在创建过程中暂停 30 秒。该暂停使实际写入进程的锁可被观察到。普通资源更新也会持有锁;人为添加 sleep 并非生产部署建议。两个配置中都包含这项受控状态变更,但尚未应用。
观察实际争用和正常释放
在这一步中,运行一个实际写入进程,并从第二个目录运行与之竞争的计划。将下面整个代码块作为一次操作执行,以免阅读停顿消耗观察窗口。
& 在后台启动操作方 A;$! 捕获其进程 ID。它的输出写入日志,便于阅读第二个操作方的错误。有次数上限的循环等待实际 S3 锁出现,而不假定固定的启动时间。if 语句让你能够检查预期失败的计划,wait 返回写入进程的实际完成状态。即使从同一个 Terminal 启动,它们也是两个独立的 Terraform 进程。
terraform -chdir=operator-a apply -auto-approve > /tmp/operator-a.log 2>&1 &
WRITER_PID=$!
echo "$WRITER_PID"
for attempt in $(seq 1 60); do
if aws s3api head-object \
--bucket coordination-team-state \
--key reports/shared.tfstate.tflock > /dev/null 2>&1; then
break
fi
sleep 1
done
aws s3api get-object \
--bucket coordination-team-state \
--key reports/shared.tfstate.tflock \
/tmp/current-lock.json
cat /tmp/current-lock.json
if terraform -chdir=operator-b plan -lock-timeout=0s; then
echo 'Unexpected: the competing plan acquired the lock.'
false
else
PLAN_EXIT=$?
echo "$PLAN_EXIT"
fi
wait "$WRITER_PID"
cat /tmp/operator-a.log
竞争计划必须以 1 退出,并显示 Error acquiring the state lock。身份验证或连接错误不能证明发生了锁争用。锁信息属于实际写入进程;上传一个与锁同名的文件,不能证明写入进程之间实现了协调。
操作方 A 应成功完成受控创建,并正常释放锁。不要禁用锁定、删除活动写入进程的锁,或使用 force-unlock 让第二个操作方继续执行。在 AWS View 中,报告存储始终可用;锁协调的是管理操作,而不是报告读取权限。
释放后从另一个工作副本继续
在这一步中,在写入进程完成后,让操作方 B 正常获取后端访问锁。第二个工作副本现在应读取更新后的共享状态,而不是独立创建另一套资源。
terraform -chdir=operator-b plan -lock-timeout=5s
预期看到 No changes。写入期间被阻止的同一个命令,现在可以正常获取和释放锁。
从两个目录检查完成后的状态:
terraform -chdir=operator-a state list
terraform -chdir=operator-b state list
两者都列出 aws_s3_bucket.reports 和 terraform_data.coordination。它们对应同一环境和共享管理记录,并非两套部署。
aws s3 \
cp s3://coordinated-daily-reports/report.txt -
原始文本仍可读取。检查状态版本历史:
aws s3api \
list-object-versions \
--bucket coordination-team-state \
--prefix reports/shared.tfstate
实际状态具有历史记录,当前对象清单中不应再存在活动的 .tflock。历史锁版本或删除标记并不是活动写入进程的锁。
terraform -chdir=operator-a plan
此处也预期看到 No changes。后台检查会区分实际 Terraform 进程争用与手动提供的锁,并验证原始报告版本、正常释放以及后续成功访问。为各自所有者保留共享存储和后端。
总结
你区分了同一环境的两个工作副本与独立环境,观察了实际的原生锁争用,并在写入进程正常释放锁后安全继续操作,没有删除活动锁。



