1.6.3.1. 什么是 terraform-docs 以及为什么和如何使用它

Terraform 模块的用户需要阅读 Registry 上的文档来学习模块的用途、用法,以及所有参数的说明。随着团队和组织规模扩大,Terraform 模块的数量和复杂度往往急剧增加,文档维护逐渐成为制约协作、审核和交付效率的关键瓶颈。terraform-docs 作为一个专注于自动化 Terraform 模块文档生成的工具,正是为了解决这一痛点而生。

1.6.3.1.1. 什么是 terraform-docs

terraform-docs 是一个用于从 Terraform 模块自动生成文档的实用工具,支持多种输出格式。它能够解析模块中的变量(variable)、输出(output)、资源(resource)、provider 等元数据,并以结构化、标准化的方式整理输出,极大降低了手工维护文档的工作量和出错概率。

官方定义:A utility to generate documentation from Terraform modules in various output formats.

——terraform-docs README

它既可以作为独立命令行工具运行,也能通过 Docker 容器、GitHub Actions 以及 pre-commit hook 等方式集成进 CI/CD 流程。

1.6.3.1.2. 为什么要使用 terraform-docs

1.6.3.1.2.1. 文档自动化,提升开发效率

手工维护 Terraform 模块文档易出错且劳动密集。随着变量、输出等的频繁变更,文档极易与实际代码脱节。terraform-docs 能自动解析最新的模块定义,并生成权威的文档,最大程度保障文档与代码的一致性。

1.6.3.1.2.2. 降低沟通成本,提升协作透明度

标准化的文档结构让团队成员、审核者、甚至外部用户可以更快理解模块的接口、输入输出和依赖关系,大幅提升代码审查、复用和模块治理的效率。

1.6.3.1.2.3. 支持多种输出格式,灵活适配团队需求

terraform-docs 支持 Markdown、JSON、YAML、Asciidoc 等多种格式,可以方便地集成到各类知识库、门户、自动化检查或下游工具链中。

1.6.3.1.2.4. 易于集成 CI/CD,保障文档持续更新

通过 GitHub Actions、pre-commit hook 等机制,可以实现文档自动生成与校验,将文档的维护“左移”到开发和提交环节,避免遗漏和落后。

1.6.3.1.3. 如何安装 terraform-docs

terraform-docs 支持多种主流平台,安装方式灵活:

1.6.3.1.3.1. 使用 Homebrew(macOS)

brew install terraform-docs
# 或使用 tap
brew install terraform-docs/tap/terraform-docs

1.6.3.1.3.2. 使用 Scoop/Chocolatey(Windows)

scoop bucket add terraform-docs https://github.com/terraform-docs/scoop-bucket
scoop install terraform-docs

# 或
choco install terraform-docs

1.6.3.1.3.3. 下载安装包

releases 页面下载对应平台的二进制文件,解压后放入 $PATH 即可。

1.6.3.1.3.4. 使用 go install(推荐给 Go 用户)

go install github.com/terraform-docs/terraform-docs@latest

1.6.3.1.3.5. 使用 Docker

无需本地安装,直接用官方镜像:

docker run --rm --volume "$(pwd):/terraform-docs" -u $(id -u) quay.io/terraform-docs/terraform-docs:0.20.0 markdown /terraform-docs

1.6.3.1.4. 如何使用 terraform-docs

1.6.3.1.4.1. 基本用法

最简单的用法是在 Terraform 模块目录下执行:

terraform-docs markdown .

这会读取当前目录下的 .tf 文件,在标准输出流中打印 Markdown 格式的模块文档。

支持的输出格式包括:

  • asciidoc(文档/表格)
  • markdown(文档/表格)
  • json
  • pretty
  • tfvarshcl / json
  • toml
  • xml
  • yaml

例如生成 JSON 文档:

terraform-docs json .

1.6.3.1.4.2. 集成到 CI/CD 和开发流程

GitHub Actions

可用官方 terraform-docs GitHub Action 实现 PR 自动生成和校验模块文档。

pre-commit hook

通过 pre-commit 配置,实现在本地提交前自动更新文档,减少漏更的风险。

Docker

如上所示,适用于无需本地安装、跨平台和 CI 场景。

1.6.3.1.4.3. 高级配置:自定义模板与 YAML 配置

terraform-docs 支持通过 .terraform-docs.yml 文件进行丰富的自定义配置。典型配置项包括:

  • 文档结构模板(如 header、footer、sections 显隐等)
  • 递归生成子模块文档
  • 文档排序规则
  • 输出文件与模式(如 inject 到 README.md 的指定位置)

一个基础的 YAML 配置示例:

formatter: "" # this is required

version: ""

header-from: main.tf
footer-from: ""

recursive:
  enabled: false
  path: modules
  include-main: true

sections:
  hide: []
  show: []

content: ""

output:
  file: ""
  mode: inject
  template: |-
    <!-- BEGIN_TF_DOCS -->
    {{ .Content }}
    <!-- END_TF_DOCS -->

output-values:
  enabled: false
  from: ""

sort:
  enabled: true
  by: name

settings:
  anchor: true
  color: true
  default: true
  description: false
  escape: true
  hide-empty: false
  html: true
  indent: 2
  lockfile: true
  read-comments: true
  required: true
  sensitive: true
  type: true

你可以通过 terraform-docs markdown table --output-file README.md --output-mode inject . 自动将模块接口文档注入到 README.md 的指定区块。

1.6.3.1.4.4. 内容自定义与模板变量

terraform-docs 的模板支持插入模块的各个部分,如:

  • {{.Inputs}} 变量输入表
  • {{.Outputs}} 输出表
  • {{.Providers}} Provider 信息
  • {{.Requirements}} 版本约束
  • 甚至支持 {{ include "path/to/file" }} 导入外部内容

以及如下函数:

  • {{ include "relative/path/to/file" }}

这些变量是所选格式化器生成的各个部分的输出。例如,当格式化器设置为 markdown table 时,{{ .Inputs }} 就是 inputs 的 Markdown 表格表示。

注意,区块的可见性参数(即 sections.showsections.hide)优先于 content 配置。

此外,content 中还有一个特殊变量:

  • {{ .Module }}

与前面提到的其他变量不同,这个变量不会根据格式化器生成区块,而是一个 Terraform module 的结构体本身。

content: |-
  可以在 content 中放置任意文本

  {{ .Header }}

  甚至可以插入到不同区块之间

  {{ .Providers }}

  顺序也不必遵循默认顺序

  {{ .Outputs }}

  可以包含任何相对路径的文件内容

  {{ include "relative/path/to/file" }}

  {{ .Inputs }}

  # 示例

  ```hcl
  {{ include "examples/foo/main.tf" }}
  ```

  ## 资源

  {{ range .Module.Resources }}
  - {{ .GetMode }}.{{ .Spec }} ({{ .Position.Filename }}#{{ .Position.Line }})
  {{- end }}

模板机制极大提升了文档的可定制性和美观性。

1.6.3.1.4.5. 兼容性和生态

terraform-docs 兼容主流 Terraform 版本,并持续维护良好。社区活跃,有详细的用户手册调用说明配置文档

1.6.3.1.5. 生成文档的脚本

Azure Verified Module 中使用如下脚本调用 terraform-docs 生成文档:

#!/usr/bin/env bash
set -e

generate_docs () {
  local dir=$1
  echo "===> Generating documentation in $dir"
  rm -f "$dir/.terraform.lock.hcl"
  terraform-docs -c ".terraform-docs.yml" "$dir"
}

echo "==> Generating root module documentation..."
generate_docs .

echo "==> Generating examples documentation..."
if [ ! -d examples ]; then
  echo "==> Error - no examples directory found"
  exit 1
fi
cd examples
subfolders=$(find ./ -maxdepth 1 -mindepth 1 -type d)
for d in $subfolders; do
  generate_docs $d
done
cd ..

echo "==> Generating sub modules documentation..."
if [ ! -d modules ]; then
  echo "==> Warning - no modules directory found"
else
  cd modules
  subfolders=$(find ./ -maxdepth 1 -mindepth 1 -type d)
  for d in $subfolders; do
    generate_docs $d
  done
  cd ..
fi

该脚本可以为模块以及所有样例生成文档。

1.6.3.1.6. 用以检查文档是否是最新的脚本

#!/usr/bin/env bash

check_docs () {
  local dir=$1
  echo "===> Generating documentation in $dir"
    cp "$dir/README.md" "$dir/README-generated.md"
  rm -f "$dir/.terraform.lock.hcl"
  terraform-docs -c ".terraform-docs.yml" "$dir"
    echo "===> Comparing documentation in $dir"
    if [ ! -z "$(diff -q "$dir/README.md" "$dir/README-generated.md")" ]; then
        echo "==> $dir/README.md is out of date. Run 'make pre-commit' to update the generated document and commit."
        mv -f "$dir/README-generated.md" "$dir/README.md"
        exit 1
    fi
    rm -f "$dir/README-generated.md"
}

echo "==> Checking root module documentation..."
check_docs .

echo "==> Checking examples documentation..."
if [ ! -d examples ]; then
  echo "==> Error - no examples directory found"
  exit 1
fi
cd examples
subfolders=$(find ./ -maxdepth 1 -mindepth 1 -type d)
for d in $subfolders; do
  check_docs $d
done
cd ..

echo "==> Checking sub modules documentation..."
if [ ! -d modules ]; then
  echo "==> Warning - no modules directory found"
else
    cd modules
    subfolders=$(find ./ -maxdepth 1 -mindepth 1 -type d)
    for d in $subfolders; do
    check_docs $d
    done
    cd ..
fi

该脚本会尝试为模块以及所有样例生成文档,但保存在 README-generated.md 文件中,通过对比该文件与 README.md 是否一致来判断文档是否已经更新。该脚本可被用于 CI/CD 流水线中,确保代码变更中包含了对文档的变更。

1.6.3.1.7. 最佳实践与治理建议

  1. 结合 pre-commit 和 PR 检查,实现文档自动化和规范化,确保文档始终体现了当前版本的模块配置。
  2. 配置内容模板,确保所有模块文档结构统一,便于团队知识传承和模块复用。
  3. 定期升级 terraform-docs,以获得更好的格式支持和新特性。

更多详细用法和最佳实践,请参考官方文档:terraform-docs.io

results matching ""

    No results matching ""