Automated Infrastructure Documentation: A Comprehensive Guide to terraform-docs

Maintaining clear and accurate documentation for Terraform modules is a persistent challenge for DevOps and cloud engineering teams. As infrastructure evolves, manually written documentation often becomes outdated, leading to discrepancies between the code and the documented reality. terraform-docs addresses this issue by serving as a powerful command-line utility that automatically generates Terraform module documentation directly from source code. This open-source tool scans Terraform configuration files and produces structured documentation, ensuring that technical details remain consistent, readable, and always up to date. By eliminating the manual burden of updating README files, teams can rely on automation to generate documentation that accurately reflects the current Terraform module implementation. This guide explores the architecture, configuration, output formats, and integration workflows of terraform-docs, providing a technical blueprint for implementing automated documentation in modern cloud engineering pipelines.

Core Functionality and Extracted Metadata

terraform-docs operates by parsing the Human Readable Code (HCL) found in Terraform configuration files. Unlike manual documentation, which requires human intervention to describe variable types and default values, terraform-docs extracts this information programmatically. The tool identifies and structures the following key metadata components:

  • Input variables, including their names, descriptions, types, default values, and whether they are required.
  • Output values, detailing the names and descriptions of values exposed by the module.
  • Provider requirements, listing the necessary providers and their version constraints.
  • Terraform version constraints, indicating the minimum or specific versions of the Terraform binary required.
  • Resource usage, which can be included to detail the specific cloud resources provisioned by the module.

This extraction process transforms raw code into human-readable structured data. For example, if a module defines an input variable instance_type with a description "EC2 instance type", a type of string, a default of t2.micro, and is marked as optional, terraform-docs captures all these attributes simultaneously. This ensures that the documentation mirrors the code's current state. If a developer changes the default instance type from t2.micro to t3.small, the next generation of the documentation will reflect t3.small automatically, removing the risk of documentation drift.

Output Formats and Markdown Integration

One of the most popular and effective output formats is the Markdown table format. This format is specifically designed to be a good fit for generating the README of a module, as it renders cleanly in GitHub, GitLab, Bitbucket, and other repository hosts that support Markdown rendering. The tool produces clean, aligned tables that are easy for humans to scan and easy for version control systems to diff.

The following table demonstrates the typical structure of the "Inputs" section generated by terraform-docs, based on a standard EC2 instance module example:

Name Description Type Default Required
instance_type EC2 instance type string t2.micro no
instance_name Name tag for the EC2 instance string n/a yes

The "Outputs" section follows a similar tabular structure, presenting the values returned by the module after terraform apply:

Name Description
instance_id ID of the EC2 instance
public_ip Public IP address of the EC2 instance

These tables are produced automatically from the Terraform source files. The tool ensures that the column alignment and header structure remain consistent, facilitating easier visual inspection during code reviews.

Configuration Management with YAML

To ensure consistent execution across different projects and team members, terraform-docs supports a configuration file named .terraform-docs.yml. This file allows developers to standardize documentation settings, such as the output format, file location, and injection mode. By centralizing these settings, teams can avoid repetitive command-line arguments and reduce the likelihood of configuration errors.

A typical .terraform-docs.yml file might contain the following content:

yaml formatter: "markdown table" output: file: "README.md" mode: "inject"

With this configuration file in place at the root of the repository or module directory, the documentation generation process is simplified to a single command:

bash terraform-docs .

This command reads the configuration, scans the current directory, and executes the generation process according to the defined parameters. The inject mode is particularly critical in this context. It tells the tool to look for specific markers within the target file and replace the content between them, rather than overwriting the entire file. This preservation of custom content around the generated blocks is essential for maintaining a professional README that includes both static instructions and dynamic technical specifications.

Generating Documentation and README Injection

The primary workflow for integrating terraform-docs involves two main commands: one for generating documentation to the terminal for verification, and one for injecting it into the target file. To generate Markdown documentation for the module and print it to the terminal for immediate review, the following command is executed:

bash terraform-docs markdown table .

This command reads all Terraform files in the current directory and prints the formatted documentation. Once the output is verified, the documentation can be injected into the README.md file. This process requires the addition of documentation markers to the README file:

markdown <!-- BEGIN_TF_DOCS --> <!-- END_TF_DOCS -->

These comments serve as anchors for the tool. The terraform-docs utility identifies the space between BEGIN_TF_DOCS and END_TF_DOCS and replaces it with the newly generated content. The command to perform this injection is:

bash terraform-docs markdown table --output-file README.md --output-mode inject .

This ensures that the README remains synchronized with the Terraform code. The --output-mode inject flag is crucial; without it, the tool might overwrite the entire file, destroying any manual text, logos, or badges placed outside the markers. The use of markers allows for a hybrid documentation approach where static content (such as installation instructions or architecture diagrams) remains untouched, while the dynamic technical specifications (inputs, outputs, providers) are updated automatically.

Installation and Platform Compatibility

terraform-docs is compatible with a wide range of operating systems and Terraform versions. The tool's compatibility with Terraform follows a specific matrix, ensuring that the parser matches the HCL version supported by the Terraform binary.

terraform-docs Version Terraform Version
>= 0.13 >= 0.15
>= 0.8, < 0.13 >= 0.12, < 0.15
< 0.8 < 0.12

Users can install terraform-docs via several package managers depending on their operating system. For macOS users, Homebrew provides a streamlined installation method:

bash brew install terraform-docs

Alternatively, the official tap can be used:

bash brew install terraform-docs/tap/terraform-docs

Windows users have options through Scoop or Chocolatey. Using Scoop requires adding the terraform-docs bucket first:

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

For Chocolatey, the installation is a single command:

bash choco install terraform-docs

Stable binaries are also available on the releases page of the GitHub repository. To install manually, users must download the binary for their platform from the "Assets" section and place it into their $PATH. The following command demonstrates downloading the binary for a Linux amd64 architecture, using version v0.24.0 as an example:

bash curl -Lo ./terraform-docs.tar.gz https://github.com/terraform-docs/terraform-docs/releases/download/v0.24.0/terraform-docs-v0.24.0-$(uname)-amd64.tar.gz tar -xzf terraform-docs.tar.gz chmod +x terraform-docs mv terraform-docs /usr/local/bin/terraform-docs

It is important to note that Windows releases are in ZIP format, whereas Linux and macOS releases are typically tar.gz. For developers who prefer installing from source, go install or go get can be used. The following commands illustrate installation via Go modules:

```bash

go1.17+

go install github.com/terraform-docs/[email protected]

go1.16

GO111MODULE="on" go get github.com/terraform-docs/[email protected]
```

A minimum of Go 1.16 is required for this method. This installation places the terraform-docs binary in $(go env GOPATH)/bin, which must be included in the system's $PATH for global execution.

Automation in CI/CD Pipelines and Pre-commit Hooks

Keeping documentation up to date is significantly easier when automated. There are two primary strategies for automation: integrating with pre-commit hooks and utilizing CI/CD pipelines.

Pre-commit Integration

Using pre-commit ensures that Terraform module documentation is kept up to date each time a developer makes a commit. This approach catches documentation drift locally, before code is pushed to the remote repository. First, the pre-commit tool must be installed. Then, a .pre-commit-config.yaml file is created or updated in the root of the Git repository with the following content:

yaml repos: - repo: https://github.com/terraform-docs/terraform-docs rev: "v0.24.0" hooks: - id: terraform-docs-go args: ["markdown", "table", "--output-file", "README.md", "./mymodule/path"]

After configuring the file, the hooks are installed with:

bash pre-commit install pre-commit install-hooks

Once installed, any further changes to the module's .tf files will cause an update to the documentation when a commit is made. If the documentation changes, pre-commit will stage the updated README.md automatically, ensuring that the commit includes both the code changes and the corresponding documentation updates.

GitHub Actions Integration

For team-wide enforcement and automated updates on pull requests, the terraform-docs GitHub Action is a robust solution. To use this action, a YAML workflow file is configured, typically located at .github/workflows/documentation.yml. The workflow triggers on pull requests and runs a job that renders the docs and pushes the changes back to the PR branch.

The following configuration demonstrates this workflow:

yaml name: Generate terraform docs on: - pull_request jobs: docs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.ref }} - name: Render terraform docs and push changes back to PR uses: terraform-docs/gh-actions@main with: working-dir: . output-file: README.md output-method: inject git-push: "true"

In this workflow, the actions/checkout@v3 step ensures that the specific branch of the pull request is checked out. The terraform-docs/gh-actions@main step then performs the documentation generation. The git-push: "true" parameter is critical, as it allows the action to commit the generated documentation and push it back to the pull request. This ensures that when a reviewer opens the pull request, they see both the code changes and the automatically updated documentation, allowing for a holistic review of the changes.

Compatibility and Versioning Considerations

When integrating terraform-docs into a new project, it is essential to verify compatibility between the version of terraform-docs and the version of Terraform used by the team. The compatibility matrix provided by the project highlights specific version pairings. For instance, terraform-docs versions 0.13 and higher are compatible with Terraform versions 0.15 and higher. Similarly, terraform-docs versions 0.8 up to but not including 0.13 are compatible with Terraform versions 0.12 up to but not including 0.15. For older environments, terraform-docs versions prior to 0.8 are compatible with Terraform versions prior to 0.12.

Understanding these pairings is crucial for preventing parsing errors. If a team upgrades their Terraform binary to a major version without updating terraform-docs, the tool may fail to parse certain HCL syntax features or may misinterpret type definitions. Therefore, it is a best practice to pin both tools to known compatible versions in your CI/CD environment or to use the latest stable release of both when performing upgrades.

Best Practices for Module Documentation

Adopting terraform-docs is a best practice for teams that build reusable Terraform modules. The tool reduces the cognitive load on developers by removing the need to manually write and maintain technical specifications. However, several best practices should be followed to maximize its effectiveness:

  • Use descriptive variable names and descriptions. The tool copies the description from the Terraform code, so if the description is empty or vague, the generated documentation will also be unhelpful.
  • Maintain the documentation markers. Ensure that <!-- BEGIN_TF_DOCS --> and <!-- END_TF_DOCS --> are present in the target file. If these markers are removed, the injection mode will fail or behave unexpectedly.
  • Automate the process. Relying on manual execution of terraform-docs leads to inconsistency. Implementing pre-commit hooks or CI/CD workflows ensures that documentation is updated with every change.
  • Review generated diffs. Even with automation, it is good practice to review the diff of the README.md in pull requests to ensure that the changes are logical and intended.

Conclusion

terraform-docs solves a fundamental problem in DevOps and cloud engineering: the maintenance of accurate technical documentation. By extracting metadata directly from Terraform configuration files, it provides a single source of truth for module inputs, outputs, and requirements. The tool's flexibility in output formats, particularly the Markdown table format, makes it ideal for integrating into repository README files. The support for configuration files and various installation methods ensures that it can be easily adopted across different operating systems and team setups. Furthermore, the integration capabilities with pre-commit and CI/CD pipelines, such as GitHub Actions, allow for fully automated documentation workflows that enforce consistency and reduce human error. For any team building scalable infrastructure with Terraform, implementing terraform-docs is not just a convenience but a critical component of professional engineering practices. It ensures that as the infrastructure evolves, the documentation remains a reliable guide for current and future developers, minimizing overhead and maximizing clarity.

Sources

  1. Devtoolhub
  2. terraform-docs.io
  3. GitHub terraform-docs

Related Posts