Home

Awesome

tfproviderlint

Static analysis libraries and tooling for Terraform Provider code.

PkgGoDev

Install

Local Install

Release binaries are available in the Releases section.

To instead use Go to install into your $GOBIN directory (e.g. $GOPATH/bin):

go install github.com/bflad/tfproviderlint/cmd/tfproviderlint@latest

If you wish to install the command which includes all linting checks, including Extra Lint Checks:

go install github.com/bflad/tfproviderlint/cmd/tfproviderlintx@latest

Docker Install

docker pull bflad/tfproviderlint

Homebrew Install

brew install bflad/tap/tfproviderlint

Usage

The tfproviderlint and tfproviderlintx tools operate similarly except for which checks are available. Additional information about usage and configuration options can be found by passing the help argument:

tfproviderlint help

To enable only specific checks, they can be passed in as flags:

tfproviderlint -AT001

To enable all checks, but disable specific checks, they can be passed in as flags set to false:

tfproviderlint -AT001=false

Local Usage

To report issues, change into the directory of the Terraform Provider code and run:

tfproviderlint ./...

To apply automated fixes for checks that support them, change into the directory of the Terraform Provider code and run:

tfproviderlint -fix ./...

It is also possible to run via go vet:

go vet -vettool $(which tfproviderlint) ./...

Docker Usage

Change into the directory of the Terraform Provider code and run:

docker run -v $(pwd):/src bflad/tfproviderlint ./...

GitHub Action Usage

A GitHub Action is available: tfproviderlint-github-action

Standard Lint Checks

Standard lint checks are enabled by default in the tfproviderlint tool. Opt-in checks can be found in the Extra Lint Checks section. For additional information about each check, you can run tfproviderlint help NAME.

Standard Acceptance Test Checks

CheckDescriptionType
AT001check for TestCase missing CheckDestroyAST
AT002check for acceptance test function names including the word importAST
AT003check for acceptance test function names missing an underscoreAST
AT004check for TestStep Config containing provider configurationAST
AT005check for acceptance test function names missing TestAcc prefixAST
AT006check for acceptance test functions containing multiple resource.Test() invocationsAST
AT007check for acceptance test functions containing multiple resource.ParallelTest() invocationsAST
AT008check for acceptance test function declaration *testing.T parameter namingAST
AT009check for acctest.RandStringFromCharSet() calls that can be simplified to acctest.RandString()AST
AT010check for TestCase including IDRefreshName implementationAST
AT011check for TestCase including IDRefreshIgnore implementation without IDRefreshNameAST
AT012check for files containing multiple acceptance test function name prefixesAST

Standard Resource Checks

CheckDescriptionType
R001check for ResourceData.Set() calls using complex key argumentAST
R002check for ResourceData.Set() calls using * dereferencesAST
R003check for Resource having Exists functionsAST
R004check for ResourceData.Set() calls using incompatible value typesAST
R005check for ResourceData.HasChange() calls that can be combined into one HasChanges() callAST
R006check for RetryFunc that omit retryable errorsAST
R007check for deprecated (schema.ResourceData).Partial usageAST
R008REMOVED in v0.30.0 check for deprecated (schema.ResourceData).SetPartial usageAST
R009check for Go panic usageAST
R010check for (schema.ResourceData).GetChange assignment which should use (schema.ResourceData).GetAST
R011check for Resource that configure MigrateStateAST
R012check for data source Resource that configure CustomizeDiffAST
R013check for map[string]*Resource that resource names contain at least one underscoreAST
R014check for CreateFunc, CreateContextFunc, DeleteFunc, DeleteContextFunc, ReadFunc, ReadContextFunc, UpdateFunc, and UpdateContextFunc parameter namingAST
R015check for (*schema.ResourceData).SetId() receiver method usage with unstable resource.UniqueId() valueAST
R016check for (*schema.ResourceData).SetId() receiver method usage with unstable resource.PrefixedUniqueId() valueAST
R017check for (*schema.ResourceData).SetId() receiver method usage with unstable time.Now() valueAST
R018check for time.Sleep() function usageAST
R019check for (*schema.ResourceData).HasChanges() receiver method usage with many argumentsAST

Standard Schema Checks

CheckDescriptionType
S001check for Schema of TypeList or TypeSet missing ElemAST
S002check for Schema with both Required and Optional enabledAST
S003check for Schema with both Required and Computed enabledAST
S004check for Schema with both Required and Default configuredAST
S005check for Schema with both Computed and Default configuredAST
S006check for Schema of TypeMap missing ElemAST
S007check for Schema with both Required and ConflictsWith configuredAST
S008check for Schema of TypeList or TypeSet with Default configuredAST
S009check for Schema of TypeList or TypeSet with ValidateFunc configuredAST
S010check for Schema of Computed only with ValidateFunc configuredAST
S011check for Schema of Computed only with DiffSuppressFunc configuredAST
S012check for Schema that Type is configuredAST
S013check for map[string]*Schema that one of Computed, Optional, or Required is configuredAST
S014check for Schema within Elem that Computed, Optional, and Required are not configuredAST
S015check for map[string]*Schema that attribute names are validAST
S016check for Schema that Set is only configured for TypeSetAST
S017check for Schema that MaxItems and MinItems are only configured for TypeList, TypeMap, or TypeSetAST
S018check for Schema that should use TypeList with MaxItems: 1AST
S019check for Schema that should omit Computed, Optional, or Required set to falseAST
S020check for Schema of Computed only with ForceNew enabledAST
S021check for Schema that should omit ComputedWhenAST
S022check for Schema of TypeMap with invalid Elem of *schema.ResourceAST
S023check for Schema that should omit Elem with incompatible TypeAST
S024check for Schema that should omit ForceNew in data source schema attributesAST
S025check for Schema of Computed only with AtLeastOneOf configuredAST
S026check for Schema of Computed only with ConflictsWith configuredAST
S027check for Schema of Computed only with Default configuredAST
S028check for Schema of Computed only with DefaultFunc configuredAST
S029check for Schema of Computed only with ExactlyOneOf configuredAST
S030check for Schema of Computed only with InputDefault configuredAST
S031check for Schema of Computed only with MaxItems configuredAST
S032check for Schema of Computed only with MinItems configuredAST
S033check for Schema of Computed only with StateFunc configuredAST
S034REMOVED in v0.30.0 check for Schema that configure PromoteSingleAST
S035check for Schema with invalid AtLeastOneOf attribute referencesAST
S036check for Schema with invalid ConflictsWith attribute referencesAST
S037check for Schema with invalid ExactlyOneOf attribute referencesAST

Standard Validation Checks

CheckDescriptionType
V001check for custom SchemaValidateFunc that implement validation.StringMatch() or validation.StringDoesNotMatch()AST
V002REMOVED in v0.30.0 check for deprecated CIDRNetwork validation function usageAST
V003REMOVED in v0.30.0 check for deprecated IPRange validation function usageAST
V004REMOVED in v0.30.0 check for deprecated SingleIP validation function usageAST
V005REMOVED in v0.30.0 check for deprecated ValidateJsonString validation function usageAST
V006REMOVED in v0.30.0 check for deprecated ValidateListUniqueStrings validation function usageAST
V007REMOVED in v0.30.0 check for deprecated ValidateRegexp validation function usageAST
V008REMOVED in v0.30.0 check for deprecated ValidateRFC3339TimeString validation function usageAST
V009check for validation.StringMatch() call with empty message argumentAST
V010check for validation.StringDoesNotMatch() call with empty message argumentAST
V011check for custom SchemaValidateFunc that implement validation.StringLenBetween()AST
V012check for custom SchemaValidateFunc that implement validation.IntAtLeast(), validation.IntAtMost(), or validation.IntBetween()AST
V013check for custom SchemaValidateFunc that implement validation.StringInSlice() or validation.StringNotInSlice()AST
V014check for custom SchemaValidateFunc that implement validation.IntInSlice() or validation.IntNotInSlice()AST

Extra Lint Checks

Extra lint checks are not included in the tfproviderlint tool and must be accessed via the tfproviderlintx tool or added to a custom lint tool. Generally these represent advanced Terraform Plugin SDK functionality that is not appropriate for all Terraform Providers.

Extra Acceptance Test Checks

CheckDescriptionType
XAT001check for TestCase missing ErrorCheckAST

Extra Resource Checks

CheckDescriptionType
XR001check for usage of ResourceData.GetOkExists() callsAST
XR002check for Resource that should implement ImporterAST
XR003check for Resource that should implement TimeoutsAST
XR004check for ResourceData.Set() calls that should implement error checking with complex valuesAST
XR005check for Resource that Description is configuredAST
XR006check for Resource that implements Timeouts for missing Create, Delete, Read, or Update implementationAST
XR007check for os/exec.Command usageAST
XR008check for os/exec.CommandContext usageAST

Extra Schema Checks

CheckDescriptionType
XS001check for map[string]*Schema that Description is configuredAST
XS002check for map[string]*Schema that keys are in alphabetical orderAST

Development and Testing

This project is built on the go/analysis framework and uses Go Modules for dependency management.

Helpful tooling for development:

Go Compatibility

This project follows the Go support policy for versions. The two latest major releases of Go are supported by the project.

Currently, that means Go 1.21 or later must be used when including this project as a dependency.

Adding an Analyzer

Implementing SuggestedFixes Testing

The upstream analysistest package now contains functionality to verify SuggestedFixes via RunWithSuggestedFixes.

import (
  "testing"

  "golang.org/x/tools/go/analysis/analysistest"
)

func TestAnalyzerFixes(t *testing.T) {
  testdata := analysistest.TestData()
  analysistest.RunWithSuggestedFixes(t, testdata, Analyzer, "testdata/src/a")
}

To setup the expected file content verification, the testing expects a file suffixed with .golden (e.g. testdata/src/a/main.go.golden).

Implementing a Custom Lint Tool

The go/analysis framework and this codebase are designed for flexibility. You may wish to permanently disable certain default checks or even implement your own provider-specific checks. An example of how to incorporate all default and extra checks in a CLI command can be found in cmd/tfproviderlintx. To permanently exclude checks, each desired Analyzer must be individually included, similar to how AllChecks() is built in passes/checks.go.

The passes directory also includes the underlying Analyzer which iteratively gather AST-based information about the Terraform Provider code being analyzed. For example, passes/helper/resource/retryfuncinfo returns information from all named and anonymous declarations of helper/resource.RetryFunc().

Primatives for working with Terraform Plugin SDK primatives can be found in helper/terraformtype. Primatives for working with the Go AST can be found in helper/astutils.

Updating Dependencies

Dependency updates are managed by Dependabot.

Unit Testing

go test ./...

Local Install Testing

go install ./cmd/tfproviderlint