A documentation generator for Terraform/OpenTofu modules, built on open-inspector.
The goal: a modern alternative to terraform-docs that matches its day-to-day
workflow, then goes further using data the inspector captures that
terraform-docs discards (source ranges, schema findings, reference graphs,
structured types).
Status: early / proof-of-concept. Today open-docs emits a verbose, debug-oriented dump of everything the inspector parses. The curated, reader-facing output and the workflow features below are planned. See the feature checklist for what works now vs. what is coming.
terraform-docs renders the fields it understands and throws the rest away.
open-inspector keeps the parts that make docs actionable, and open-docs turns
them into output:
- Source permalinks. Every block carries
filename+ start/endline:column:byte, so docs can deep-link to the exact source lines on GitHub/GitLab/Bitbucket. - Health, not just a field dump. Schema findings (deprecated, unknown, missing-required attributes) and missing descriptions become an actionable checklist with severities.
- Diagrams. The inspector's module graph (tree/DOT/Mermaid) becomes inline dependency and resource diagrams; GitHub renders Mermaid natively.
- Richer data. Leading
# ...doc-comments, structured variable types (object({ ... })withoptional), decoded default values, and expression-level references (var.x,module.y.z,aws_s3_bucket.b). - Fuller block coverage than terraform-docs:
moved,import,removed,check,ephemeral, and OpenTofuencryption.
- Inspect a module directory and render Markdown for every block type (providers, inputs, outputs, locals, managed/data/ephemeral resources, module calls, moved/import/removed, checks, schema findings, diagnostics).
- Full source position per row (
`file.tf` [L:C:B -> L:C:B]). - Doc-comments, structured types, decoded defaults, and expression references surfaced in the table view.
- [~] Curated, reader-facing default layout. Today the output is the verbose
all-columns debug view; a clean default with
--verboseas the opt-in debug mode is planned. - [~ ] Section toggles (show/hide) and sort order (by name or source position).
- [~ ] Deterministic, diff-stable output across runs and platforms.
- Write to stdout or a file (
-o). - README injection between
<!-- BEGIN_OPEN_DOC -->/<!-- END_OPEN_DOC -->markers instead of overwriting the file (output { mode = "inject" }). - [~] Config file (
.open-docs.hcl):output { file, mode }works today; formatter, sections, sort, and header/footer source are planned. - prek hooks for file hygiene, gofmt,
go vet, andgo test. - GitHub Action wrapper.
- CI gate:
--check(fail if on-disk docs are stale) and--fail-on warning|error.
- Schema-aware inspection via
-schema(shells out totofu/terraform). - [~] Health section: render schema findings + missing descriptions as a severity checklist. Findings render as a table today; the curated health view is planned.
- Source permalinks: ranges -> host links at the right ref/line, with git remote/ref detection and config override.
- Inline Mermaid graph: module dependency and resource-relationship diagrams.
- Cross-references ("used by"): drive from expression references
(e.g. which outputs/resources consume
var.x). - Lint/quality: unused variables, unreferenced outputs, undocumented inputs/outputs, doc-completeness score.
- Dynamic config (HCL eval context): build section lists with
for/conditionals that react to the inspected module. - Templates / custom content: arrange generated sections and interleave prose or included files.
- More formats: Markdown document,
json,mdx,asciidoc. - Recursive / multi-module docs via the module graph.
- Examples extraction: include
examples/*/main.tfsnippets. - Optional static HTML/MDX site output.
go build -o open-docs .
# print to stdout
./open-docs ./examples/vpc
# write to a file (replace mode)
./open-docs -o ./examples/vpc/README.md ./examples/vpc
# enrich with provider schema (deprecated / missing-required findings)
# requires `tofu` or `terraform` available and the module initialized
./open-docs -schema ./examples/vpc# Built-in defaults for open-docs. A user's .open-docs.hcl is decoded on top
# of these values, so any attribute set there overrides the one here.
main {
docsfile = "README.md"
mode = "stdout"
# mode = "replace"
header = true
}
required {
render = true
name = true
source = true
version = true
alias = false
position = true
}
providers {
render = true
name = true
alias = true
for_each = false
position = true
}
variables {
render = true
name = true
type = true
default = true
required = true
description = true
comment = true
sensitive = true
nullable = true
ephemeral = true
validation = true
position = true
}
outputs {
render = true
name = true
value = true
references = true
description = true
comment = true
sensitive = true
ephemeral = true
depends_on = true
position = true
}
locals {
render = true
name = true
value = true
references = true
position = true
}
resources {
render = true
name = true
mode = false
type = true
provider = false
count = true
for_each = true
depends_on = true
nested_body= true
lifecycle = true
comment = true
position = true
}Drop a .open-docs.hcl in the module directory or the repository root (or pass
-config <file>) to control output. open-docs uses the nearest one, searching
from the module directory up to the repository root.
main {
docsfile = "README.md" # relative to the module directory
mode = "inject" # "stdout" (default) | "replace" | "inject"
header = false # omit the module title and path lines (default: true)
}In inject mode, open-docs replaces the text between the markers and leaves the
rest of the file untouched (creating the region if it is missing):
# My Module
Hand-written intro.
<!-- BEGIN_OPEN_DOC -->
<!-- END_OPEN_DOC -->The -o <file> flag is a shortcut for replace mode to that path and takes
precedence over the config file.
Each directory under examples/ is a module with its generated
README.md, used to check how output renders:
- vpc: a realistic multi-file AWS VPC module with a local child module.
- complete: every block type open-inspector understands
(including ephemeral, check, OpenTofu encryption and provider
for_each, and a.tf.jsonfile), plus table edge cases such as pipes, heredocs, Unicode, and long values. - invalid: deliberately broken configuration for the diagnostics table.
The project uses devenv for a pinned Go, OpenTofu, and prek toolchain. Enter it directly or allow direnv once:
devenv shell
# or
direnv allowThe shell installs the prek Git shim. Common commands are:
build # compile ./open-docs
format # format all Go files
verify # format check, build, vet, test, and smoke test
prek run --all-files # run every repository hook
devenv test # run the complete devenv verificationopen-docs calls inspector.Inspect(dir) to parse the module into a
*model.Module, then walks that struct in markdown.go to
render Markdown tables. All HCL parsing lives in open-inspector; open-docs owns
presentation only.
main.go: CLI flag parsing, callsinspector.Inspect, writes output.markdown.go: renders a*model.Moduleto Markdown.examples/: sample modules and their generatedREADME.md.
- open-inspector: the HCL inspection engine open-docs is built on.
- terraform-docs: the incumbent open-docs aims to match, then surpass.