1.6.4.1. terrafmt
在大型基础设施自动化项目中,Terraform 配置往往不仅存在于 .tf
文件本身,还会被嵌入到 Markdown 文档、测试代码、模板字符串,甚至 Go 语言源代码中。如何在保证这些嵌入式 HCL 片段可读性的同时,持续维护高质量和一致的代码风格?这正是 terrafmt
诞生的初衷。
terrafmt
是一个命令行工具,专为提取、格式化、升级和检查嵌入在各类文件中的 Terraform 配置块而设计。它的目标类似于 terraform fmt
,但适用范围更广,支持处理代码和文档中的多种嵌套场景。
1.6.4.1.1. terrafmt 的核心功能
- 提取和格式化嵌入式 Terraform 块
terrafmt
能自动识别以下代码块中的 HCL 代码片段,并对其进行格式化:
start | end |
---|---|
```hcl | ``` |
```tf | `, |
```terraform | `, |
return fmt.Sprintf(` | `, |
return fmt.Sprintf(` | `) |
return ` | ` |
例如,假设有如下 Markdown 文件:
```hcl
resource "aws_instance" "example" {
ami = "ami-2757f631"
instance_type = "t2.micro"
}
```
使用 terrafmt
,可以自动将其格式化为更清晰、缩进规范的形式:
```hcl
resource "aws_instance" "example" {
ami = "ami-2757f631"
instance_type = "t2.micro"
}
```
- 批量处理与差异检查
我们可以通过如下命令批量格式化目录下所有 .md
文件中的 Terraform 块:
find . | egrep ".md" | sort | while read f; do terrafmt fmt -f $f; done
也可以用 diff 命令,预览哪些地方会被格式化:
terrafmt diff -f README.md
- 丰富的输出和集成方式
terrafmt
支持用纯文本、JSON 等多种格式输出提取到的代码块,便于自动化集成与代码分析。同时通过不同命令返回不同的退出码,方便在 CI/CD 流程中进行自动格式检查和阻断。
1.6.4.1.2. 典型命令用法
- 提取文件中的 Terraform 块
terrafmt blocks README.md
- 只显示需要格式化的差异
terrafmt diff -f README.md
- 格式化并直接更新文件
terrafmt fmt -f README.md
- 检查格式化差异并在 CI 中用退出码阻断
terrafmt diff --check -f .
1.6.4.1.3. 与传统 terraform fmt 的区别和优势
与官方的 terraform fmt
工具不同,terrafmt
能够处理非纯 .tf
文件中的嵌入式配置块。无论是在 Markdown 文档、Provider 测试代码、还是模板字符串中,只要代码块用合适的标记包裹,都可以被自动提取和规范化。这对于需要统一治理大量文档、测试和模块样例的团队极为重要。
此外,terrafmt
对 Go 模板(如 %[1]s
)等特殊语法也有良好兼容,解决了 terraform fmt
无法直接处理此类字符串的问题。
1.6.4.1.4. AVM 中对 terrafmt 的使用
AVM 中使用以下脚本对文档和潜在的 Terratest 代码中的 HCL 代码做格式化处理:
echo "==> Fixing test and document terraform blocks code with terrafmt..."
files=$(find . -type f -name "*.md" -o -name "*.go" | grep -v -e ".github" -e "-terraform" -e "vendor" -e ".terraform" -e "README.md" -e "README-generated.md")
for f in $files; do
terrafmt fmt -f "$f"
retValue=$?
if [ $retValue -ne 0 ]; then
echo "------------------------------------------------"
echo ""
echo "The preceding files contain terraform blocks that are not correctly formatted or contain errors."
echo ""
exit $retValue
fi
done
然后用以下脚本检查 Pull Request 提交的变更是否弄乱了文档中的 HCL 代码格式:
#!/usr/bin/env bash
echo "==> Checking documentation terraform blocks are formatted..."
files=$(find . -type f -name "*.md" -o -name "*.go" | grep -v -e ".github" -e "-terraform" -e "vendor" -e ".terraform" -e "README.md")
error=false
for f in $files; do
terrafmt diff -c -q "$f"
retValue=$?
if [ $retValue -ne 0 ] && [ $retValue -ne 2 ]; then
error=true
fi
done
if ${error}; then
echo "------------------------------------------------"
echo ""
echo "The preceding files contain terraform blocks that are not correctly formatted or contain errors."
echo "You can fix this by running make tools and then terrafmt on them."
echo ""
echo "to easily fix all terraform blocks:"
echo "$ make terrafmt"
echo ""
exit 1
fi
exit 0