Terraform Guide

Terraform module registry documentation: what a consumer sees, and what is missing from it

By the engineer who builds Datadef, from client work on data platforms · Reviewed August 21, 2026

A module page in a registry is assembled from two things: the inputs and outputs read out of the source, and your README rendered underneath. The public registry has always worked that way, and GitLab added README rendering to its own Terraform module registry in 17.2. Which means the quality of your module documentation is the quality of one markdown file plus whatever a table can express.

6 min readFor maintainers publishing Terraform modules to a public or private registry

See it as a diagram

Everything below, as a diagram you can edit. Describe yours and see it in seconds.

155/20003 credits left
Try:

No account needed · Editable canvas, not a picture

What the generated half already covers

Inputs, outputs, providers, and required versions come out of the source automatically, on the registry page and in a README section if you run terraform-docs. Hand-maintaining any of that is wasted effort, and a module whose input table is stale is usually a module whose maintainer edited the table instead of the code.

The gap is the same everywhere: a consumer reading the module page can tell what they may pass in and cannot tell what they will get. Usage examples help with the first question, not the second. A module that creates a bucket, a key, a service account, and three IAM bindings looks, from the input table, exactly like a module that creates a bucket.

A module library repository has no stack, and that is handled

Module repositories are structurally odd, and the convention makes them so. HashiCorp's Standard Module Structure puts examples of using the module under examples/ at the root, so the only directories that qualify as root modules are usually the demos. Naive analysis draws them and calls it a day, which produces a diagram of example code rather than of the module.

Datadef sets aside directories whose path contains a segment reading as examples, tests, fixtures, e2e, wrappers, or ci. When those are the only root modules, the referenced module with the most resources is promoted to be the subject instead. A module that accounts for more than half of everything visible in the repository also earns a deeper budget, sixteen drawn nodes rather than the eight a module gets when it is one component among many, because compressing the subject of the repository into eight boxes would hide the thing being documented.

Pin the picture to the tag you released

Module documentation has a versioning problem that repository documentation does not. Consumers pin to v5.8.1 and read the page for v5.8.1, so a diagram generated from main is wrong for most of the people looking at it.

A Datadef project is bound to a repository plus a branch or a tag, so connect the tag. The project synced from v5.8.1 keeps showing the v5.8.1 architecture, and a new release gets its own connection. Put the live embed line in the README of that tag and the module page carries a picture that matches the code the consumer is actually calling.

One markdown image line is the whole integration, it renders in the registry and in GitHub, GitLab, or Azure DevOps alike, and no account is needed to view it. Mermaid is the usual alternative and it has the opposite trade-off: it renders natively in some hosts and not others, and somebody has to hand-edit it every time the module changes.

# terraform-google-secure-bucket

![What this module builds](https://datadef.io/api/embed/secure-bucket-a1b2c3d4)

## Usage

```hcl
module "bucket" {
  source  = "acme/secure-bucket/google"
  version = "5.8.1"
  name    = "analytics-raw"
}
```

<!-- terraform-docs inputs and outputs below -->

What belongs on the module page, in order

One sentence saying what the module owns. The picture. The smallest working usage example, because that is the block people copy. Then the generated input and output tables. Then the notes that no generator can produce: what the module deliberately does not create, which inputs are load-bearing for security, and what a caller has to provision first.

That last group is the highest-value prose in module documentation and the part most often missing, because it is the only part that requires a decision rather than a command. For the repository-level version of the same argument, see the Terraform documentation generator.

FAQ

How do I put a diagram on a Terraform module registry page?

Registry pages render your README, so a single markdown image line pointing at a live embed URL puts the diagram at the top of the module page. It renders anywhere markdown renders images, including GitHub, GitLab, and Azure DevOps, it follows the source diagram when that changes, and no account is needed to view it.

Does the analysis work on a repository that has no root module?

Yes. When the only root modules are examples, tests, or fixtures, they are set aside and the module they demonstrate becomes the subject of the diagram, with a deeper node budget of sixteen drawn nodes so the module itself is not compressed away.

Can a diagram be pinned to a released module version?

Yes, and for a published module it should be. A repository connection is bound to a branch or a tag, so connecting the release tag produces a project that keeps showing that version of the architecture, which is what consumers pinned to it are reading. A later release is connected as its own project with its own embed line.

Does this replace terraform-docs?

No, and it does not try to. terraform-docs generates the input, output, provider, and requirement tables, which nothing here duplicates. The addition is the architecture layer: a diagram of what the module builds, plus a doc whose module reference table lists each module with its source and resource count. Most published modules benefit from both.

Why an image instead of a Mermaid block in the README?

Mermaid renders natively in some hosts and not in others, and it has to be hand-edited whenever the module changes. A live embed renders anywhere markdown supports images and follows the source diagram, so nobody has to remember to update it.