A utility to generate documentation from Terraform modules in various output formats.
macOS users can install using Homebrew:
brew install terraform-docs
or
brew install terraform-docs/tap/terraform-docs
Windows users can install using Scoop:
scoop bucket add terraform-docs https://github.com/terraform-docs/scoop-bucket
scoop install terraform-docs
or Chocolatey:
choco install terraform-docs
Stable binaries are also available on the releases page. To install, download the
binary for your platform from "Assets" and place this into your $PATH
:
curl -Lo ./terraform-docs.tar.gz https://github.com/terraform-docs/terraform-docs/releases/download/v0.18.0/terraform-docs-v0.18.0-$(uname)-amd64.tar.gz
tar -xzf terraform-docs.tar.gz
chmod +x terraform-docs
mv terraform-docs /usr/local/bin/terraform-docs
NOTE: Windows releases are in ZIP
format.
The latest version can be installed using go install
or go get
:
# go1.17+
go install github.com/terraform-docs/[email protected]
# go1.16
GO111MODULE="on" go get github.com/terraform-docs/[email protected]
NOTE: please use the latest Go to do this, minimum go1.16
is required.
This will put terraform-docs
in $(go env GOPATH)/bin
. If you encounter the error
terraform-docs: command not found
after installation then you may need to either add
that directory to your $PATH
as shown here or do a manual installation by cloning
the repo and run make build
from the repository which will put terraform-docs
in:
$(go env GOPATH)/src/github.com/terraform-docs/terraform-docs/bin/$(uname | tr '[:upper:]' '[:lower:]')-amd64/terraform-docs
To run and generate documentation into README within a directory:
terraform-docs markdown table --output-file README.md --output-mode inject /path/to/module
Check output
configuration for more details and examples.
terraform-docs can be run as a container by mounting a directory with .tf
files in it and run the following command:
docker run --rm --volume "$(pwd):/terraform-docs" -u $(id -u) quay.io/terraform-docs/terraform-docs:0.18.0 markdown /terraform-docs
If output.file
is not enabled for this module, generated output can be redirected
back to a file:
docker run --rm --volume "$(pwd):/terraform-docs" -u $(id -u) quay.io/terraform-docs/terraform-docs:0.18.0 markdown /terraform-docs > doc.md
NOTE: Docker tag latest
refers to latest stable released version and edge
refers to HEAD of master
at any given point in time.
To use terraform-docs GitHub Action, configure a YAML workflow file (e.g.
.github/workflows/documentation.yml
) with the following:
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"
Read more about terraform-docs GitHub Action and its configuration and examples.
With pre-commit, you can ensure your Terraform module documentation is kept up-to-date each time you make a commit.
First install pre-commit and then create or update a .pre-commit-config.yaml
in the root of your Git repo with at least the following content:
repos:
- repo: https://github.com/terraform-docs/terraform-docs
rev: "v0.18.0"
hooks:
- id: terraform-docs-go
args: ["markdown", "table", "--output-file", "README.md", "./mymodule/path"]
Then run:
pre-commit install
pre-commit install-hooks
Further changes to your module's .tf
files will cause an update to documentation
when you make a commit.
terraform-docs can be configured with a yaml file. The default name of this file is
.terraform-docs.yml
and the path order for locating it is:
- root of module directory
.config/
folder at root of module directory- current directory
.config/
folder at current directory$HOME/.tfdocs.d/
formatter: "" # this is required
version: ""
header-from: main.tf
footer-from: ""
recursive:
enabled: false
path: modules
include-main: true
sections:
hide: []
show: []
content: ""
output:
file: ""
mode: inject
template: |-
<!-- BEGIN_TF_DOCS -->
{{ .Content }}
<!-- END_TF_DOCS -->
output-values:
enabled: false
from: ""
sort:
enabled: true
by: name
settings:
anchor: true
color: true
default: true
description: false
escape: true
hide-empty: false
html: true
indent: 2
lockfile: true
read-comments: true
required: true
sensitive: true
type: true
Generated content can be customized further away with content
in configuration.
If the content
is empty the default order of sections is used.
Compatible formatters for customized content are asciidoc
and markdown
. content
will be ignored for other formatters.
content
is a Go template with following additional variables:
{{ .Header }}
{{ .Footer }}
{{ .Inputs }}
{{ .Modules }}
{{ .Outputs }}
{{ .Providers }}
{{ .Requirements }}
{{ .Resources }}
and following functions:
{{ include "relative/path/to/file" }}
These variables are the generated output of individual sections in the selected
formatter. For example {{ .Inputs }}
is Markdown Table representation of inputs
when formatter is set to markdown table
.
Note that sections visibility (i.e. sections.show
and sections.hide
) takes
precedence over the content
.
Additionally there's also one extra special variable avaialble to the content
:
{{ .Module }}
As opposed to the other variables mentioned above, which are generated sections
based on a selected formatter, the {{ .Module }}
variable is just a struct
representing a Terraform module.
content: |-
Any arbitrary text can be placed anywhere in the content
{{ .Header }}
and even in between sections
{{ .Providers }}
and they don't even need to be in the default order
{{ .Outputs }}
include any relative files
{{ include "relative/path/to/file" }}
{{ .Inputs }}
# Examples
```hcl
{{ include "examples/foo/main.tf" }}
```
## Resources
{{ range .Module.Resources }}
- {{ .GetMode }}.{{ .Spec }} ({{ .Position.Filename }}#{{ .Position.Line }})
{{- end }}
terraform-docs primary use-case is to be utilized as a standalone binary, but some parts of it is also available publicly and can be imported in your project as a library.
import (
"github.com/terraform-docs/terraform-docs/format"
"github.com/terraform-docs/terraform-docs/print"
"github.com/terraform-docs/terraform-docs/terraform"
)
// buildTerraformDocs for module root `path` and provided content `tmpl`.
func buildTerraformDocs(path string, tmpl string) (string, error) {
config := print.DefaultConfig()
config.ModuleRoot = path // module root path (can be relative or absolute)
module, err := terraform.LoadWithOptions(config)
if err != nil {
return "", err
}
// Generate in Markdown Table format
formatter := format.NewMarkdownTable(config)
if err := formatter.Generate(module); err != nil {
return "", err
}
// // Note: if you don't intend to provide additional template for the generated
// // content, or the target format doesn't provide templating (e.g. json, yaml,
// // xml, or toml) you can use `Content()` function instead of `Render()`.
// // `Content()` returns all the sections combined with predefined order.
// return formatter.Content(), nil
return formatter.Render(tmpl)
}
Generated output can be heavily customized with content
, but if using that
is not enough for your use-case, you can write your own plugin.
In order to install a plugin the following steps are needed:
- download the plugin and place it in
~/.tfdocs.d/plugins
(or./.tfdocs.d/plugins
) - make sure the plugin file name is
tfdocs-format-<NAME>
- modify
formatter
of.terraform-docs.yml
file to be<NAME>
Important notes:
- if the plugin file name is different than the example above, terraform-docs won't be able to to pick it up nor register it properly
- you can only use plugin thorough
.terraform-docs.yml
file and it cannot be used with CLI arguments
To create a new plugin create a new repository called tfdocs-format-<NAME>
with
following main.go
:
package main
import (
_ "embed" //nolint
"github.com/terraform-docs/terraform-docs/plugin"
"github.com/terraform-docs/terraform-docs/print"
"github.com/terraform-docs/terraform-docs/template"
"github.com/terraform-docs/terraform-docs/terraform"
)
func main() {
plugin.Serve(&plugin.ServeOpts{
Name: "<NAME>",
Version: "0.1.0",
Printer: printerFunc,
})
}
//go:embed sections.tmpl
var tplCustom []byte
// printerFunc the function being executed by the plugin client.
func printerFunc(config *print.Config, module *terraform.Module) (string, error) {
tpl := template.New(config,
&template.Item{Name: "custom", Text: string(tplCustom)},
)
rendered, err := tpl.Render("custom", module)
if err != nil {
return "", err
}
return rendered, nil
}
Please refer to tfdocs-format-template for more details. You can create a new
repository from it by clicking on Use this template
button.
- Users
- Read the User Guide to learn how to use terraform-docs
- Read the Formats Guide to learn about different output formats of terraform-docs
- Refer to Config File Reference for all the available configuration options
- Developers
- Read Contributing Guide before submitting a pull request
Visit our website for all documentation.
- Discuss terraform-docs on Slack
MIT License - Copyright (c) 2021 The terraform-docs Authors.