mirror of
https://github.com/terraform-docs/terraform-docs.git
synced 2026-03-27 12:58:35 +07:00
Merge pull request #651 from kampka/ignore-input-vars
Ignore inputs with terraform-docs-ignore comment
This commit is contained in:
@@ -4,7 +4,7 @@ description: "How to generate terraform.tfvars file with terraform-docs"
|
||||
menu:
|
||||
docs:
|
||||
parent: "how-to"
|
||||
weight: 207
|
||||
weight: 208
|
||||
toc: false
|
||||
---
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ description: "How to use terraform-docs with GitHub Actions"
|
||||
menu:
|
||||
docs:
|
||||
parent: "how-to"
|
||||
weight: 208
|
||||
weight: 209
|
||||
toc: false
|
||||
---
|
||||
|
||||
|
||||
74
docs/how-to/ignore-resources.md
Normal file
74
docs/how-to/ignore-resources.md
Normal file
@@ -0,0 +1,74 @@
|
||||
---
|
||||
title: "Ignore Resources to be Generated"
|
||||
description: "How to ignore resources from generated output"
|
||||
menu:
|
||||
docs:
|
||||
parent: "how-to"
|
||||
weight: 204
|
||||
toc: false
|
||||
---
|
||||
|
||||
Since `v0.18.0`
|
||||
|
||||
Any type of resources can be ignored from the generated output by prepending them
|
||||
with a comment `terraform-docs-ignore`. Supported type of Terraform resources to
|
||||
get ignored are:
|
||||
|
||||
- `resource`
|
||||
- `data`
|
||||
- `module`
|
||||
- `variable`
|
||||
- `output`
|
||||
|
||||
{{< alert type="info" >}}
|
||||
If a `resource` or `data` is ignored, their corresponding discovered provider
|
||||
will also get ignored from "Providers" section.
|
||||
{{< /alert>}}
|
||||
|
||||
Take the following example:
|
||||
|
||||
```hcl
|
||||
##################################################################
|
||||
# All of the following will be ignored from the generated output #
|
||||
##################################################################
|
||||
|
||||
# terraform-docs-ignore
|
||||
resource "foo_resource" "foo" {}
|
||||
|
||||
# This resource is going to get ignored from generated
|
||||
# output by using the following known comment.
|
||||
#
|
||||
# terraform-docs-ignore
|
||||
#
|
||||
# The ignore keyword also doesn't have to be the first,
|
||||
# last, or the only thing in a leading comment
|
||||
resource "bar_resource" "bar" {}
|
||||
|
||||
# terraform-docs-ignore
|
||||
data "foo_data_resource" "foo" {}
|
||||
|
||||
# terraform-docs-ignore
|
||||
data "bar_data_resource" "bar" {}
|
||||
|
||||
// terraform-docs-ignore
|
||||
module "foo" {
|
||||
source = "foo"
|
||||
version = "x.x.x"
|
||||
}
|
||||
|
||||
# terraform-docs-ignore
|
||||
variable "foo" {
|
||||
default = "foo"
|
||||
}
|
||||
|
||||
// terraform-docs-ignore
|
||||
output "foo" {
|
||||
value = "foo"
|
||||
}
|
||||
```
|
||||
|
||||
{{< alert type="info" >}}
|
||||
The ignore keyword (i.e. `terraform-docs-ignore`) doesn't have to be the first,
|
||||
last, or only thing in a leading comment. As long as the keyword is present in
|
||||
a comment, the following resource will get ignored.
|
||||
{{< /alert>}}
|
||||
@@ -4,7 +4,7 @@ description: "How to include example in terraform-docs generated output"
|
||||
menu:
|
||||
docs:
|
||||
parent: "how-to"
|
||||
weight: 205
|
||||
weight: 206
|
||||
toc: false
|
||||
---
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ description: "How to insert generated terraform-docs output to file"
|
||||
menu:
|
||||
docs:
|
||||
parent: "how-to"
|
||||
weight: 204
|
||||
weight: 205
|
||||
toc: false
|
||||
---
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ description: "How to use pre-commit hooks with terraform-docs"
|
||||
menu:
|
||||
docs:
|
||||
parent: "how-to"
|
||||
weight: 209
|
||||
weight: 210
|
||||
toc: false
|
||||
---
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ description: "How to generate submodules documentation recursively with terrafor
|
||||
menu:
|
||||
docs:
|
||||
parent: "how-to"
|
||||
weight: 206
|
||||
weight: 207
|
||||
toc: false
|
||||
---
|
||||
|
||||
|
||||
@@ -63,8 +63,20 @@ data "aws_caller_identity" "ident" {
|
||||
provider = "aws.ident"
|
||||
}
|
||||
|
||||
# terraform-docs-ignore
|
||||
data "aws_caller_identity" "ignored" {
|
||||
provider = "aws"
|
||||
}
|
||||
|
||||
resource "null_resource" "foo" {}
|
||||
|
||||
# This resource is going to get ignored from generated
|
||||
# output by using the following known comment.
|
||||
# terraform-docs-ignore
|
||||
# And the ignore keyword also doesn't have to be the first,
|
||||
# last, or only thing in a leading comment
|
||||
resource "null_resource" "ignored" {}
|
||||
|
||||
module "bar" {
|
||||
source = "baz"
|
||||
version = "4.5.6"
|
||||
@@ -84,3 +96,9 @@ module "baz" {
|
||||
module "foobar" {
|
||||
source = "git@github.com:module/path?ref=v7.8.9"
|
||||
}
|
||||
|
||||
// terraform-docs-ignore
|
||||
module "ignored" {
|
||||
source = "foobaz"
|
||||
version = "7.8.9"
|
||||
}
|
||||
|
||||
@@ -17,3 +17,8 @@ output "output-0.12" {
|
||||
value = join(",", var.list-3)
|
||||
description = "terraform 0.12 only"
|
||||
}
|
||||
|
||||
// terraform-docs-ignore
|
||||
output "ignored" {
|
||||
value = "ignored"
|
||||
}
|
||||
|
||||
@@ -14,6 +14,11 @@ variable "bool-1" {
|
||||
default = true
|
||||
}
|
||||
|
||||
# terraform-docs-ignore
|
||||
variable "ignored" {
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "string-3" {
|
||||
default = ""
|
||||
}
|
||||
|
||||
2
go.mod
2
go.mod
@@ -17,6 +17,7 @@ require (
|
||||
github.com/spf13/viper v1.18.2
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/terraform-docs/terraform-config-inspect v0.0.0-20210728164355-9c1f178932fa
|
||||
golang.org/x/exp v0.0.0-20240525044651-4c93da0ed11d
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
honnef.co/go/tools v0.3.2
|
||||
mvdan.cc/xurls/v2 v2.5.0
|
||||
@@ -58,7 +59,6 @@ require (
|
||||
github.com/zclconf/go-cty v1.14.4 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/crypto v0.23.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240525044651-4c93da0ed11d // indirect
|
||||
golang.org/x/exp/typeparams v0.0.0-20220722155223-a9213eeb770e // indirect
|
||||
golang.org/x/mod v0.17.0 // indirect
|
||||
golang.org/x/net v0.25.0 // indirect
|
||||
|
||||
@@ -187,10 +187,17 @@ func loadInputs(tfmodule *tfconfig.Module, config *print.Config) ([]*Input, []*I
|
||||
var optional = make([]*Input, 0, len(tfmodule.Variables))
|
||||
|
||||
for _, input := range tfmodule.Variables {
|
||||
comments := loadComments(input.Pos.Filename, input.Pos.Line)
|
||||
|
||||
// skip over inputs that are marked as being ignored
|
||||
if strings.Contains(comments, "terraform-docs-ignore") {
|
||||
continue
|
||||
}
|
||||
|
||||
// convert CRLF to LF early on (https://github.com/terraform-docs/terraform-docs/issues/305)
|
||||
inputDescription := strings.ReplaceAll(input.Description, "\r\n", "\n")
|
||||
if inputDescription == "" && config.Settings.ReadComments {
|
||||
inputDescription = loadComments(input.Pos.Filename, input.Pos.Line)
|
||||
inputDescription = comments
|
||||
}
|
||||
|
||||
i := &Input{
|
||||
@@ -245,13 +252,20 @@ func loadModulecalls(tfmodule *tfconfig.Module, config *print.Config) []*ModuleC
|
||||
var source, version string
|
||||
|
||||
for _, m := range tfmodule.ModuleCalls {
|
||||
source, version = formatSource(m.Source, m.Version)
|
||||
comments := loadComments(m.Pos.Filename, m.Pos.Line)
|
||||
|
||||
// skip over modules that are marked as being ignored
|
||||
if strings.Contains(comments, "terraform-docs-ignore") {
|
||||
continue
|
||||
}
|
||||
|
||||
description := ""
|
||||
if config.Settings.ReadComments {
|
||||
description = loadComments(m.Pos.Filename, m.Pos.Line)
|
||||
description = comments
|
||||
}
|
||||
|
||||
source, version = formatSource(m.Source, m.Version)
|
||||
|
||||
modules = append(modules, &ModuleCall{
|
||||
Name: m.Name,
|
||||
Source: source,
|
||||
@@ -277,10 +291,17 @@ func loadOutputs(tfmodule *tfconfig.Module, config *print.Config) ([]*Output, er
|
||||
}
|
||||
}
|
||||
for _, o := range tfmodule.Outputs {
|
||||
comments := loadComments(o.Pos.Filename, o.Pos.Line)
|
||||
|
||||
// skip over outputs that are marked as being ignored
|
||||
if strings.Contains(comments, "terraform-docs-ignore") {
|
||||
continue
|
||||
}
|
||||
|
||||
// convert CRLF to LF early on (https://github.com/terraform-docs/terraform-docs/issues/584)
|
||||
description := strings.ReplaceAll(o.Description, "\r\n", "\n")
|
||||
if description == "" && config.Settings.ReadComments {
|
||||
description = loadComments(o.Pos.Filename, o.Pos.Line)
|
||||
description = comments
|
||||
}
|
||||
|
||||
output := &Output{
|
||||
@@ -330,7 +351,11 @@ func loadOutputValues(config *print.Config) (map[string]*output, error) {
|
||||
return terraformOutputs, err
|
||||
}
|
||||
|
||||
func loadProviders(tfmodule *tfconfig.Module, config *print.Config) []*Provider {
|
||||
func loadProviders(tfmodule *tfconfig.Module, config *print.Config) []*Provider { //nolint:gocyclo
|
||||
// NOTE(khos2ow): this function is over our cyclomatic complexity goal.
|
||||
// Be wary when adding branches, and look for functionality that could
|
||||
// be reasonably moved into an injected dependency.
|
||||
|
||||
type provider struct {
|
||||
Name string `hcl:"name,label"`
|
||||
Version string `hcl:"version"`
|
||||
@@ -360,6 +385,13 @@ func loadProviders(tfmodule *tfconfig.Module, config *print.Config) []*Provider
|
||||
|
||||
for _, resource := range resources {
|
||||
for _, r := range resource {
|
||||
comments := loadComments(r.Pos.Filename, r.Pos.Line)
|
||||
|
||||
// skip over resources that are marked as being ignored
|
||||
if strings.Contains(comments, "terraform-docs-ignore") {
|
||||
continue
|
||||
}
|
||||
|
||||
var version = ""
|
||||
if l, ok := lock[r.Provider.Name]; ok {
|
||||
version = l.Version
|
||||
@@ -368,6 +400,10 @@ func loadProviders(tfmodule *tfconfig.Module, config *print.Config) []*Provider
|
||||
}
|
||||
|
||||
key := fmt.Sprintf("%s.%s", r.Provider.Name, r.Provider.Alias)
|
||||
if _, ok := discovered[key]; ok {
|
||||
continue
|
||||
}
|
||||
|
||||
discovered[key] = &Provider{
|
||||
Name: r.Provider.Name,
|
||||
Alias: types.String(r.Provider.Alias),
|
||||
@@ -384,6 +420,7 @@ func loadProviders(tfmodule *tfconfig.Module, config *print.Config) []*Provider
|
||||
for _, provider := range discovered {
|
||||
providers = append(providers, provider)
|
||||
}
|
||||
|
||||
return providers
|
||||
}
|
||||
|
||||
@@ -420,6 +457,13 @@ func loadResources(tfmodule *tfconfig.Module, config *print.Config) []*Resource
|
||||
|
||||
for _, resource := range allResources {
|
||||
for _, r := range resource {
|
||||
comments := loadComments(r.Pos.Filename, r.Pos.Line)
|
||||
|
||||
// skip over resources that are marked as being ignored
|
||||
if strings.Contains(comments, "terraform-docs-ignore") {
|
||||
continue
|
||||
}
|
||||
|
||||
var version string
|
||||
if rv, ok := tfmodule.RequiredProviders[r.Provider.Name]; ok {
|
||||
version = resourceVersion(rv.VersionConstraints)
|
||||
@@ -437,7 +481,7 @@ func loadResources(tfmodule *tfconfig.Module, config *print.Config) []*Resource
|
||||
|
||||
description := ""
|
||||
if config.Settings.ReadComments {
|
||||
description = loadComments(r.Pos.Filename, r.Pos.Line)
|
||||
description = comments
|
||||
}
|
||||
|
||||
discovered[key] = &Resource{
|
||||
|
||||
@@ -11,12 +11,14 @@ the root directory of this source tree.
|
||||
package terraform
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"golang.org/x/exp/slices"
|
||||
|
||||
"github.com/terraform-docs/terraform-docs/print"
|
||||
)
|
||||
@@ -38,6 +40,7 @@ func TestLoadModuleWithOptions(t *testing.T) {
|
||||
assert.Equal(true, module.HasModuleCalls())
|
||||
assert.Equal(true, module.HasProviders())
|
||||
assert.Equal(true, module.HasRequirements())
|
||||
assert.Equal(true, module.HasResources())
|
||||
|
||||
config.Sections.Header = false
|
||||
config.Sections.Footer = true
|
||||
@@ -774,6 +777,87 @@ func TestLoadProviders(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadRequirements(t *testing.T) {
|
||||
type expected struct {
|
||||
requirements []string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
path string
|
||||
expected expected
|
||||
}{
|
||||
{
|
||||
name: "load module requirements from path",
|
||||
path: "full-example",
|
||||
expected: expected{
|
||||
requirements: []string{"terraform >= 0.12", "aws >= 2.15.0"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "load module requirements from path",
|
||||
path: "no-requirements",
|
||||
expected: expected{
|
||||
requirements: []string{},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
module, _ := loadModule(filepath.Join("testdata", tt.path))
|
||||
requirements := loadRequirements(module)
|
||||
|
||||
assert.Equal(len(tt.expected.requirements), len(requirements))
|
||||
|
||||
for i, r := range tt.expected.requirements {
|
||||
assert.Equal(r, fmt.Sprintf("%s %s", requirements[i].Name, requirements[i].Version))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadResources(t *testing.T) {
|
||||
type expected struct {
|
||||
resources []string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
path string
|
||||
expected expected
|
||||
}{
|
||||
{
|
||||
name: "load module resources from path",
|
||||
path: "full-example",
|
||||
expected: expected{
|
||||
resources: []string{"tls_private_key.baz", "aws_caller_identity.current", "null_resource.foo"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "load module resources from path",
|
||||
path: "no-resources",
|
||||
expected: expected{
|
||||
resources: []string{},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
config := print.NewConfig()
|
||||
module, _ := loadModule(filepath.Join("testdata", tt.path))
|
||||
resources := loadResources(module, config)
|
||||
|
||||
assert.Equal(len(tt.expected.resources), len(resources))
|
||||
|
||||
for _, r := range resources {
|
||||
assert.True(slices.Contains(tt.expected.resources, fmt.Sprintf("%s_%s.%s", r.ProviderName, r.Type, r.Name)))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadComments(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
14
terraform/testdata/full-example/main.tf
vendored
14
terraform/testdata/full-example/main.tf
vendored
@@ -21,8 +21,16 @@ data "aws_caller_identity" "current" {
|
||||
provider = "aws"
|
||||
}
|
||||
|
||||
# terraform-docs-ignore
|
||||
data "aws_caller_identity" "ignored" {
|
||||
provider = "aws"
|
||||
}
|
||||
|
||||
resource "null_resource" "foo" {}
|
||||
|
||||
# terraform-docs-ignore
|
||||
resource "null_resource" "ignored" {}
|
||||
|
||||
module "foo" {
|
||||
source = "bar"
|
||||
version = "1.2.3"
|
||||
@@ -35,3 +43,9 @@ module "foobar" {
|
||||
locals {
|
||||
arn = provider::aws::arn_parse("arn:aws:iam::444455556666:role/example")
|
||||
}
|
||||
|
||||
// terraform-docs-ignore
|
||||
module "ignored" {
|
||||
source = "baz"
|
||||
version = "1.2.3"
|
||||
}
|
||||
|
||||
5
terraform/testdata/full-example/outputs.tf
vendored
5
terraform/testdata/full-example/outputs.tf
vendored
@@ -17,3 +17,8 @@ output "B" {
|
||||
output "D" {
|
||||
value = null
|
||||
}
|
||||
|
||||
# terraform-docs-ignore
|
||||
output "ignored" {
|
||||
value = "e"
|
||||
}
|
||||
|
||||
6
terraform/testdata/full-example/variables.tf
vendored
6
terraform/testdata/full-example/variables.tf
vendored
@@ -28,3 +28,9 @@ variable "G" {
|
||||
description = "G description"
|
||||
default = null
|
||||
}
|
||||
|
||||
# terraform-docs-ignore
|
||||
variable "ignored" {
|
||||
description = "H description"
|
||||
default = null
|
||||
}
|
||||
|
||||
0
terraform/testdata/no-requirements/main.tf
vendored
Normal file
0
terraform/testdata/no-requirements/main.tf
vendored
Normal file
0
terraform/testdata/no-resources/main.tf
vendored
Normal file
0
terraform/testdata/no-resources/main.tf
vendored
Normal file
@@ -7,3 +7,8 @@ variable "B" {
|
||||
output "B" {
|
||||
value = "b"
|
||||
}
|
||||
|
||||
// terraform-docs-ignore
|
||||
output "ignored" {
|
||||
value = "c"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user