Customizing Documentation Standards¶
Overview¶
ThothCTL generates IaC documentation using terraform-docs under the hood. You can use the built-in standards as-is, or provide a custom configuration file to control exactly what gets generated.
Prerequisites¶
terraform-docs must be installed and available in your PATH:
# macOS
brew install terraform-docs
# Linux
curl -sSLo ./terraform-docs.tar.gz https://terraform-docs.io/dl/v0.18.0/terraform-docs-v0.18.0-$(uname)-amd64.tar.gz
tar -xzf terraform-docs.tar.gz
chmod +x terraform-docs
sudo mv terraform-docs /usr/local/bin/
# Verify
terraform-docs --version
Built-in Documentation Standards¶
ThothCTL ships with two documentation standards, selected via --mood:
stacks (default)¶
Designed for full infrastructure projects (Terragrunt stacks, root modules).
Characteristics:
- Output mode: replace (overwrites entire README)
- Includes dependency graph SVG reference
- Shows: header, requirements, providers, modules, resources, inputs, outputs
- Sorted by: name
Generated README structure:
<!-- BEGIN_TF_DOCS -->
# Module Header (from main.tf)
## Code Dependencies Graph

## Requirements
## Providers
## Modules
## Resources
## Inputs
## Outputs
<!-- END_TF_DOCS -->
modules¶
Designed for reusable Terraform modules with examples.
Characteristics:
- Output mode: inject (preserves content outside markers)
- Includes inline example from examples/complete/main.tf
- Shows: header, requirements, providers, modules, resources, inputs, outputs
- Sorted by: required
- Adds "DO NOT EDIT" notice
Generated README structure:
# Your custom content here (preserved)
<!-- BEGIN_TF_DOCS -->
# Module Header
## Example
```hcl
// Content of examples/complete/main.tf inlined here
```
## Requirements
## Providers
## Inputs
## Outputs
<!-- END_TF_DOCS -->
# More custom content (preserved)
Note:
resourcesis a backward-compatible alias forstacks.
Metadata in Terraform Files¶
terraform-docs extracts metadata from your .tf files to populate the documentation. Understanding where content comes from helps you write better docs.
Header (module description)¶
The header-from config option (default: main.tf) pulls the first comment block at the top of that file:
/**
* # My Networking Module
*
* Creates a VPC with public and private subnets across multiple
* availability zones. Includes NAT gateways and route tables.
*
* ## Features
* - Multi-AZ deployment
* - Configurable CIDR ranges
* - Optional VPN gateway
*/
resource "aws_vpc" "this" {
# ...
}
This becomes the {{ .Header }} content in the generated README.
Footer¶
Similarly, footer-from pulls content from a separate file (e.g., docs/footer.md):
Variable descriptions¶
Input/output tables are built from description attributes:
variable "vpc_cidr" {
description = "CIDR block for the VPC. Must be /16 or larger."
type = string
default = "10.0.0.0/16"
validation {
condition = can(cidrhost(var.vpc_cidr, 0))
error_message = "Must be a valid CIDR block."
}
}
variable "environment" {
description = "Deployment environment (dev, staging, prod)."
type = string
}
output "vpc_id" {
description = "ID of the created VPC."
value = aws_vpc.this.id
}
Generated table:
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| vpc_cidr | CIDR block for the VPC. Must be /16 or larger. | string |
"10.0.0.0/16" |
no |
| environment | Deployment environment (dev, staging, prod). | string |
n/a | yes |
Best practices for tf metadata¶
- Always add
descriptionto every variable and output — empty descriptions produce blank table cells - Use the top comment block in
main.tffor module-level documentation (purpose, features, usage notes) - Keep descriptions concise — one line; use the header comment block for extended explanations
- Add
typeexplicitly — terraform-docs renders the type column from it - Set
defaultwhere appropriate — it shows users what's optional vs required
README Markers (Required)¶
Your README.md must contain these markers for documentation injection to work:
Without these markers, terraform-docs cannot determine where to write the output and will silently skip the file.
For new projects, add them to your README template:
Custom Configuration File¶
To fully customize the documentation output, create a terraform-docs.yml and pass it with --config-file:
When --config-file is provided, it completely overrides the built-in standard. ThothCTL passes it directly to terraform-docs.
Minimal Custom Config¶
formatter: "markdown table"
sections:
show:
- requirements
- inputs
- outputs
output:
file: "README.md"
mode: inject
template: |-
<!-- BEGIN_TF_DOCS -->
{{ .Content }}
<!-- END_TF_DOCS -->
sort:
enabled: true
by: required
Full Custom Config (all options)¶
formatter: "markdown table"
# Pull header text from this file
header-from: main.tf
footer-from: ""
# Which sections to include
sections:
hide: []
show:
- header
- requirements
- providers
- modules
- resources
- inputs
- outputs
- footer
# Custom content template with Golang template syntax
content: |-
{{ .Header }}
## Architecture

## Usage
```hcl
module "this" {
source = "git::https://github.com/myorg/this-module.git?ref=v1.0.0"
// Required
name = "example"
environment = "dev"
}
```
{{ .Requirements }}
{{ .Providers }}
{{ .Modules }}
{{ .Resources }}
{{ .Inputs }}
{{ .Outputs }}
{{ .Footer }}
# Output configuration
output:
file: "README.md"
mode: inject # "inject" preserves content outside markers
# "replace" overwrites the entire file
template: |-
<!-- BEGIN_TF_DOCS -->
{{ .Content }}
<!-- END_TF_DOCS -->
# Sort inputs/outputs
sort:
enabled: true
by: required # "required", "name", or "type"
# Display settings
settings:
anchor: true
color: true
default: true
description: false
escape: true
hide-empty: false
html: true
indent: 2
lockfile: true
required: true
sensitive: true
type: true
Key Configuration Options¶
| Option | Values | Description |
|---|---|---|
output.mode |
inject, replace |
inject preserves content outside markers; replace overwrites the file |
sort.by |
name, required, type |
How to sort inputs and outputs |
header-from |
filename | File to extract the module description from (first comment block) |
content |
Go template | Full control over document structure using {{ .Section }} placeholders |
sections.show |
list | Which sections to include |
sections.hide |
list | Which sections to exclude |
Available Template Placeholders¶
| Placeholder | Content |
|---|---|
{{ .Header }} |
Module description from header-from file |
{{ .Footer }} |
Content from footer-from file |
{{ .Requirements }} |
Required Terraform and provider versions |
{{ .Providers }} |
Provider configurations |
{{ .Modules }} |
Child module calls |
{{ .Resources }} |
Resources created |
{{ .Inputs }} |
Input variables table |
{{ .Outputs }} |
Output values table |
{{ include "path" }} |
Inline content from a file |
Per-Project Configuration¶
You can commit a .terraform-docs.yml in your project root. When using --config-file, point to it:
Recommended project structure:
my-project/
├── .terraform-docs.yml ← your custom standard
├── modules/
│ ├── networking/
│ │ ├── main.tf
│ │ └── README.md ← generated
│ └── compute/
│ ├── main.tf
│ └── README.md ← generated
└── stacks/
└── prod/
├── main.tf
└── README.md ← generated
Exclude Patterns¶
The --exclude option uses substring matching (not glob). Any directory whose path contains the pattern is skipped:
# Exclude .terraform caches and example directories
thothctl document iac -f terraform --recursive \
--exclude .terraform \
--exclude examples \
--exclude test
⚠️ --exclude modules would skip any directory with "modules" in the path. Be specific.
End-to-End Examples¶
Generate docs for a Terragrunt stack project¶
# Default standard (stacks) + SVG dependency graph
thothctl document iac -f terragrunt --recursive
# With mermaid graph instead
thothctl document iac -f terragrunt --recursive --graph-type mermaid
Generate docs for a reusable module¶
# Uses 'modules' standard — includes example code inline
thothctl document iac -f terraform --mood modules
Use organization-wide standard¶
# Store your standard in the Space templates directory
# then reference it in all projects:
thothctl document iac -f terraform --recursive \
--config-file ~/.thothcf/spaces/production/templates/terraform-docs.yml
CI/CD: Auto-generate and commit¶
- name: Generate documentation
run: |
thothctl document iac -f terragrunt --recursive --graph-type mermaid
git diff --quiet || git commit -am "docs: auto-update IaC documentation"
Troubleshooting¶
| Issue | Cause | Solution |
|---|---|---|
| README not updated | Missing <!-- BEGIN_TF_DOCS --> markers |
Add markers to your README.md |
command not found: terraform-docs |
Not installed | Install terraform-docs (see Prerequisites) |
| Empty output | No .tf files in directory |
Ensure directory contains Terraform files |
| Sections missing | Not listed in sections.show |
Add desired sections to your config |
include fails |
File path relative to module root | Use relative path from the documented directory |