Stage 4 · Provision
Modules & Composition
Module Documentation
terraform-docs, examples, READMEs, generated inputs, and runnable usage contracts — documenting modules for consumers.
Why Document Modules?
Module documentation is the contract between the module author and consumers. Without it, consumers must read the source code to understand inputs, outputs, and behavior. Good documentation accelerates adoption and reduces support requests.
terraform-docs
$ terraform-docs markdown table . > README.md
$ terraform-docs markdown document . > docs/README.md
$ terraform-docs asciidoc . > README.adoc
$ terraform-docs json . > docs.json
$ terraform-docs yaml . > docs.yamlterraform-docs auto-generates documentation from Terraform files. The markdown table format is the most common. Run it after every variable or output change to keep docs current.
# .terraform-docs.yml
formatter: markdown table
output:
file: README.md
mode: replace
sort:
enabled: true
by: required
content: |-
{{ .Content }}
## Usage
```hcl
module "example" {
source = "../modules/vpc"
cidr = "10.0.0.0/16"
}
```The configuration file controls formatting, output location, and content. The content block adds custom text. The sort option orders variables by required first.
README Patterns
# VPC Module
Creates an AWS VPC with public and private subnets.
## Features
- Configurable CIDR block
- Public and private subnets
- NAT gateway (optional)
- Flow logs (optional)
## Usage
~~~hcl
module "vpc" {
source = "registry.example.com/org/vpc/aws"
version = "~> 2.0"
name = "my-vpc"
cidr = "10.0.0.0/16"
env = "prod"
}
~~~
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|----------|
| name | Name prefix | string | n/a | yes |
| cidr | VPC CIDR | string | "10.0.0.0/16" | no |A good README starts with a one-line summary, then lists features. The usage section shows a minimal example. Inputs/outputs tables should include type, default, and whether required.
Example Configurations
modules/vpc/
main.tf
variables.tf
outputs.tf
README.md
examples/
basic/
main.tf
outputs.tf
advanced/
main.tf
outputs.tf
variables.tfThe examples directory contains runnable configurations. Each example demonstrates a different use case. Consumers can copy examples as starting points.
module "vpc" {
source = "../../"
name = "example-vpc"
cidr = "10.0.0.0/16"
}
output "vpc_id" {
value = module.vpc.vpc_id
}The basic example uses default values. The source path uses ../../ to reference the parent module. This example is self-contained and runnable.
Auto-Generated Docs
name: Update Documentation
on:
push:
paths:
- 'modules/*/variables.tf'
- 'modules/*/outputs.tf'
jobs:
docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Generate docs
run: |
for module in modules/*/; do
terraform-docs markdown table "$module" > "$module/README.md"
done
- name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "Auto-update module documentation"The workflow triggers when variables or outputs change. It generates documentation for all modules. The auto-commit action pushes the updated docs.
Documentation Standards
- Every module must have a README.md.
- Include a usage example for the most common configuration.
- Auto-generate input/output tables with terraform-docs.
- Document all validation rules and their purpose.
- Include examples for advanced configurations.
- Update documentation when variables or outputs change.
Add terraform-docs to your CI pipeline. Check that documentation is up-to-date by comparing generated output with committed README. This prevents documentation drift.
If documentation is not auto-generated, it will become outdated. Stale documentation misleads consumers. Use terraform-docs to keep documentation in sync with code.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.