介绍
你的团队已有通过 Terraform 管理的报告存储。在引入自动化部署之前,你需要一个作业,在生成计划之前拒绝格式不规范或结构无效的配置。
你将配置两道静态检查关卡,观察每道关卡如何阻止实际作业继续执行,并修复配置。你应已了解 Terraform 配置、计划和状态、Git 基础知识以及 shell 退出状态。已准备好的环境无需个人 AWS 账户。
与认证考试的关联
| 认证 | 考试任务 | 实践内容 |
|---|---|---|
| DevOps Engineer – Professional (DOP-C02) | 任务 1.2 | 在后续交付阶段之前设置自动化静态检查,并在退出状态表明失败时停止执行的基础实践。 |

在生成计划之前添加检查
在这一步中,你将把静态检查接入已提供的顺序执行作业。现有存储桶和报告是背景基础设施:本实验必须保持它们的数据和 Terraform 状态不变。
使用 Terminal 界面。进入已提供的 Git 仓库,并加载其工具环境。source 将预先准备的变量应用到当前 shell;它不会部署基础设施。
cd /home/labex/project/report-delivery
source environment.sh
检查资源配置和当前作业阶段。cat 显示各文件的内容,让你了解作业管理什么以及执行什么。
cat main.tf pipeline.json
存储桶有一个 Purpose 标签。作业目前只有一个 plan 阶段。仅计划成功并不能证明已先执行格式和结构检查。
terraform fmt -check 检查配置是否符合 Terraform 的规范格式,不会重写文件。terraform validate 检查已初始化配置的内部一致性,包括资源属性是否受支持。两者都不能证明配置满足业务需求;下一个实验将介绍模块断言。
提供的执行器将阶段名称映射到固定的 Terraform 命令,并在首次出错时停止。保持 run-job.py 不变:你的任务是配置 pipeline.json,而不是重写提供的执行器。检查程序会先确认工作入口与提供的原始版本一致,再评估其行为。在生成计划之前添加这两项检查。here-document 将其分隔符之间的 JSON 写入 pipeline.json;给 EOF 加引号会保留其中的原样内容。
cat > pipeline.json <<'EOF'
{"stages":["fmt","validate","plan"]}
EOF
使用 Python 的标准解释器运行作业。这是用于教学的本地运行器;其各阶段执行标准 Terraform 命令。
python3 run-job.py
预期看到 [fmt] native exit 0、[validate] native exit 0 和 [plan] native exit 0。计划显示没有变更,因为提供的基础设施已经与配置一致。发生错误会阻止后续阶段执行。包含变更的计划使用原生命令退出码 2,运行器会将其视为成功预览,绝不视为允许 apply。
使用 Git 检查你的更改。-- 将路径与命令选项分隔开。
git diff -- pipeline.json
差异应显示两道新增关卡都位于 plan 之前。此作业没有 apply 阶段。
遇到格式错误时停止
在这一步中,你将引入一个有效但空格不符合规范的 HCL 表达式,然后证明格式关卡会在生成计划之前停止作业。
追加一个小型输出块。>> 向现有文件追加内容。此处紧凑的空格写法是刻意安排的;该输出不会管理新资源。
cat >> main.tf <<'EOF'
output "format_probe" {value="spacing"}
EOF
再次运行作业。此命令预期会失败;失败正是这里需要观察的结果。
python3 run-job.py
第一阶段报告原生命令退出码 3,并列出 main.tf。作业输出 Job stopped; later stages did not run.。不应出现 [validate] 或 [plan] 行。无需连接 AWS 即可修正格式。
检查具体建议进行哪些格式调整。-diff 显示这些调整,而 -check 保持文件不变。
terraform fmt -check -diff
此命令也会按预期返回非零退出状态。保留格式缺陷以供本步骤检查;下一步将修复它。
区分格式规范与结构有效
在这一步中,你将修复格式,然后引入另一种只有结构验证才能发现的错误。
首先让 Terraform 原地重写空格格式。运行不带 -check 的 fmt 会执行格式修改。
terraform fmt
输出列出 main.tf。确认修复后的配置能够通过作业。
python3 run-job.py
所有阶段都应执行。新增的输出可能使 plan 返回原生命令退出码 2;它提出一项输出变更,但不会应用该变更。
现在追加一个对 S3 存储桶资源未提供的属性的引用。此块使用规范格式,因此能够通过第一道关卡。
cat >> main.tf <<'EOF'
output "missing" {
value = aws_s3_bucket.reports.missing_attribute
}
EOF
先单独检查格式。
terraform fmt -check
该命令返回零且没有输出。然后运行完整作业。
python3 run-job.py
预期格式关卡通过,随后 validate 返回原生命令退出码 1,并显示 Unsupported attribute 诊断信息。不应出现 plan 阶段的输出行。表达式的格式正确,但引用了不受支持的属性。保留此错误以供步骤检查。
修复配置并保持环境不变
在这一步中,你将恢复已知有效的资源配置,重新运行设有关卡的作业,并验证报告存储未发生变化。
git restore -- main.tf 仅从仓库的起始提交恢复此文件。它会移除两个实验性输出,并保留你对独立文件 pipeline.json 的更改。
git restore -- main.tf
再次运行完整作业。
python3 run-job.py
三个阶段都应返回原生命令退出码 0。计划应显示没有变更。通过静态检查允许生成计划;这不代表批准部署,也不会应用部署。
直接从存储中读取报告。- 将内容发送到标准输出,而不是再保存一份本地副本。
aws s3 cp s3://delivery-gates-reports/report.csv -
预期输出:
quarter,total
Q1,320
检查本练习必须保留的相邻报告。
aws s3 cp s3://delivery-gates-neighbor/keep.txt -
它的内容应仍为 preserve neighboring report。查看最终的 Git 差异,确认你保留下来的更改是流水线配置。
git diff -- main.tf pipeline.json
不要销毁任何一个预先准备的存储桶:它们代表团队拥有的现有基础设施。此作业没有部署或保存计划的阶段,因此不会留下需要清理的新云资源或计划产物。恢复 main.tf 已移除临时的输出实验。保留你的质量关卡以供最终检查。
总结
你构建了一个顺序执行的 Terraform 作业,在生成计划之前进行格式检查和结构验证。你观察到格式错误和独立的不受支持属性错误如何阻止后续阶段执行,随后修复了配置,并保留了报告数据和状态。
静态有效性只是其中一层质量保障。在下一个实验中,可执行的模块断言将检查有效配置是否产生预期行为。有关本实验所用检查的详细说明,请参阅官方的 fmt 参考文档和 validate 参考文档。



