tfproviderlint
Static analysis libraries and tooling for Terraform Provider code.
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
Check | Description | Type |
---|---|---|
AT001 | check for TestCase missing CheckDestroy |
AST |
AT002 | check for acceptance test function names including the word import | AST |
AT003 | check for acceptance test function names missing an underscore | AST |
AT004 | check for TestStep Config containing provider configuration |
AST |
AT005 | check for acceptance test function names missing TestAcc prefix |
AST |
AT006 | check for acceptance test functions containing multiple resource.Test() invocations |
AST |
AT007 | check for acceptance test functions containing multiple resource.ParallelTest() invocations |
AST |
AT008 | check for acceptance test function declaration *testing.T parameter naming |
AST |
AT009 | check for acctest.RandStringFromCharSet() calls that can be simplified to acctest.RandString() |
AST |
AT010 | check for TestCase including IDRefreshName implementation |
AST |
AT011 | check for TestCase including IDRefreshIgnore implementation without IDRefreshName |
AST |
AT012 | check for files containing multiple acceptance test function name prefixes | AST |
Standard Resource Checks
Check | Description | Type |
---|---|---|
R001 | check for ResourceData.Set() calls using complex key argument |
AST |
R002 | check for ResourceData.Set() calls using * dereferences |
AST |
R003 | check for Resource having Exists functions |
AST |
R004 | check for ResourceData.Set() calls using incompatible value types |
AST |
R005 | check for ResourceData.HasChange() calls that can be combined into one HasChanges() call |
AST |
R006 | check for RetryFunc that omit retryable errors |
AST |
R007 | check for deprecated (schema.ResourceData).Partial usage |
AST |
R008 | check for deprecated (schema.ResourceData).SetPartial usage |
AST |
R009 | check for Go panic usage | AST |
R010 | check for (schema.ResourceData).GetChange assignment which should use (schema.ResourceData).Get |
AST |
R011 | check for Resource that configure MigrateState |
AST |
R012 | check for data source Resource that configure CustomizeDiff |
AST |
R013 | check for map[string]*Resource that resource names contain at least one underscore |
AST |
R014 | check for CreateFunc , CreateContextFunc , DeleteFunc , DeleteContextFunc , ReadFunc , ReadContextFunc , UpdateFunc , and UpdateContextFunc parameter naming |
AST |
R015 | check for (*schema.ResourceData).SetId() receiver method usage with unstable resource.UniqueId() value |
AST |
R016 | check for (*schema.ResourceData).SetId() receiver method usage with unstable resource.PrefixedUniqueId() value |
AST |
R017 | check for (*schema.ResourceData).SetId() receiver method usage with unstable time.Now() value |
AST |
R018 | check for time.Sleep() function usage |
AST |
R019 | check for (*schema.ResourceData).HasChanges() receiver method usage with many arguments |
AST |
Standard Schema Checks
Check | Description | Type |
---|---|---|
S001 | check for Schema of TypeList or TypeSet missing Elem |
AST |
S002 | check for Schema with both Required and Optional enabled |
AST |
S003 | check for Schema with both Required and Computed enabled |
AST |
S004 | check for Schema with both Required and Default configured |
AST |
S005 | check for Schema with both Computed and Default configured |
AST |
S006 | check for Schema of TypeMap missing Elem |
AST |
S007 | check for Schema with both Required and ConflictsWith configured |
AST |
S008 | check for Schema of TypeList or TypeSet with Default configured |
AST |
S009 | check for Schema of TypeList or TypeSet with ValidateFunc configured |
AST |
S010 | check for Schema of Computed only with ValidateFunc configured |
AST |
S011 | check for Schema of Computed only with DiffSuppressFunc configured |
AST |
S012 | check for Schema that Type is configured |
AST |
S013 | check for map[string]*Schema that one of Computed , Optional , or Required is configured |
AST |
S014 | check for Schema within Elem that Computed , Optional , and Required are not configured |
AST |
S015 | check for map[string]*Schema that attribute names are valid |
AST |
S016 | check for Schema that Set is only configured for TypeSet |
AST |
S017 | check for Schema that MaxItems and MinItems are only configured for TypeList , TypeMap , or TypeSet |
AST |
S018 | check for Schema that should use TypeList with MaxItems: 1 |
AST |
S019 | check for Schema that should omit Computed , Optional , or Required set to false |
AST |
S020 | check for Schema of Computed only with ForceNew enabled |
AST |
S021 | check for Schema that should omit ComputedWhen |
AST |
S022 | check for Schema of TypeMap with invalid Elem of *schema.Resource |
AST |
S023 | check for Schema that should omit Elem with incompatible Type |
AST |
S024 | check for Schema that should omit ForceNew in data source schema attributes |
AST |
S025 | check for Schema of Computed only with AtLeastOneOf configured |
AST |
S026 | check for Schema of Computed only with ConflictsWith configured |
AST |
S027 | check for Schema of Computed only with Default configured |
AST |
S028 | check for Schema of Computed only with DefaultFunc configured |
AST |
S029 | check for Schema of Computed only with ExactlyOneOf configured |
AST |
S030 | check for Schema of Computed only with InputDefault configured |
AST |
S031 | check for Schema of Computed only with MaxItems configured |
AST |
S032 | check for Schema of Computed only with MinItems configured |
AST |
S033 | check for Schema of Computed only with StateFunc configured |
AST |
S034 | check for Schema that configure PromoteSingle |
AST |
S035 | check for Schema with invalid AtLeastOneOf attribute references |
AST |
S036 | check for Schema with invalid ConflictsWith attribute references |
AST |
S037 | check for Schema with invalid ExactlyOneOf attribute references |
AST |
Standard Validation Checks
Check | Description | Type |
---|---|---|
V001 | check for custom SchemaValidateFunc that implement validation.StringMatch() or validation.StringDoesNotMatch() |
AST |
V002 | check for deprecated CIDRNetwork validation function usage |
AST |
V003 | check for deprecated IPRange validation function usage |
AST |
V004 | check for deprecated SingleIP validation function usage |
AST |
V005 | check for deprecated ValidateJsonString validation function usage |
AST |
V006 | check for deprecated ValidateListUniqueStrings validation function usage |
AST |
V007 | check for deprecated ValidateRegexp validation function usage |
AST |
V008 | check for deprecated ValidateRFC3339TimeString validation function usage |
AST |
V009 | check for validation.StringMatch() call with empty message argument |
AST |
V010 | check for validation.StringDoesNotMatch() call with empty message argument |
AST |
V011 | check for custom SchemaValidateFunc that implement validation.StringLenBetween() |
AST |
V012 | check for custom SchemaValidateFunc that implement validation.IntAtLeast() , validation.IntAtMost() , or validation.IntBetween() |
AST |
V013 | check for custom SchemaValidateFunc that implement validation.StringInSlice() or validation.StringNotInSlice() |
AST |
V014 | check 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
Check | Description | Type |
---|---|---|
XAT001 | check for TestCase missing ErrorCheck |
AST |
Extra Resource Checks
Check | Description | Type |
---|---|---|
XR001 | check for usage of ResourceData.GetOkExists() calls |
AST |
XR002 | check for Resource that should implement Importer |
AST |
XR003 | check for Resource that should implement Timeouts |
AST |
XR004 | check for ResourceData.Set() calls that should implement error checking with complex values |
AST |
XR005 | check for Resource that Description is configured |
AST |
XR006 | check for Resource that implements Timeouts for missing Create , Delete , Read , or Update implementation |
AST |
XR007 | check for os/exec.Command usage |
AST |
XR008 | check for os/exec.CommandContext usage |
AST |
Extra Schema Checks
Check | Description | Type |
---|---|---|
XS001 | check for map[string]*Schema that Description is configured |
AST |
XS002 | check for map[string]*Schema that keys are in alphabetical order |
AST |
Development and Testing
This project is built on the go/analysis
framework and uses Go Modules for dependency management.
Helpful tooling for development:
astdump
: a tool for displaying the AST form of Go filessadump
: a tool for displaying and interpreting the SSA form of Go programs
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.19 or later must be used when including this project as a dependency.
Adding an Analyzer
- Create new analyzer in
passes/
(orxpasses/
for extra checks) - If the
Analyzer
reports issues, add toAllChecks
variable inpasses/checks.go
(orxpasses/checks.go
for extra checks) - Since the
analysistest
package does not support Go Modules currently, each analyzer that implements testing must add a symlink to the top levelvendor
directory in thetestdata/src/a
directory. e.g.ln -s ../../../../../vendor passes/NAME/testdata/src/a/vendor
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, "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