terraform-linters / tflint

A Pluggable Terraform Linter
Mozilla Public License 2.0
4.98k stars 357 forks source link

Add support for inspecting files other than *.tf #1949

Open wata727 opened 11 months ago

wata727 commented 11 months ago

Introduction

TFLint allows anyone to implement checks on Terraform configurations using the plugin SDK. However, although the current SDK exposes many APIs for modules, it does not have enough APIs for other files that compose Terraform configurations, such as .terraform.lock.hcl, *.tfvars, and so on.

Related: https://github.com/terraform-linters/tflint/discussions/1912 https://github.com/terraform-linters/tflint-ruleset-terraform/discussions/151

Proposal

First, add a Runner API like GetHCLFile(filename string) (*hcl.File, error) to the SDK. This is similar to the existing the GetFile API, except that it can access arbitrary HCL files. The GetFile API can only access the loaded HCL files by the parser, as shown below:

https://github.com/terraform-linters/tflint/blob/0b0626648896241e0cebd68ddaebed45331a4624/plugin/server.go#L73-L81

The GetFile API will be deprecated because its name makes it difficult to understand that it can only access HCL files. For similar reasons, the GetFiles API should also be renamed to something like GetModuleSources.

Note that if you have access to an arbitrary HCL expression, it may not always be possible to evaluate it with the EvaluateExpr API. EvaluateExpr is specialized for evaluating in module context, so evaluating the expression elsewhere does not guarantee correct results. There may need to be a mechanism to prevent this mistake, but in my opinion I believe there are very few cases where it actually becomes a problem.

Another concern is autofix. If you want to support autofix for arbitrary HCL files, you will need to propagate the changes to the Runner when applying them. For example, if you want to autofix *.tfvars, you need to update the variables in the Evaluator.

https://github.com/terraform-linters/tflint/blob/0b0626648896241e0cebd68ddaebed45331a4624/plugin/server.go#L219-L221

Since this is a low-level API, it might be nice to have an API that returns a higher-level struct that is more accessible from plugins. For example, an API like GetTerraformLockFile that returns lock information in .terraform.lock.hcl. However, it is best to start with a low-level API and add to it as needed.

That said, given requests like https://github.com/terraform-linters/tflint-ruleset-terraform/discussions/151, it might be useful to have an API like GetVariableDefinitions that returns all variable definitions, regardless of file name.

So far, I have mainly mentioned adding support for HCL files, but I'm wondering how to support other files. Imagine inspecting a file such as .terraform-version, *.tftpl, and so on. The current EmitIssue API requires hcl.Range as the issue range, so it is not intended to emit issues from outside of HCL files. It may be necessary to add a new API to emit issues with something other than hcl.Range, but I haven't found a concrete approach for this yet. Maybe this will help us find another solution to solve https://github.com/terraform-linters/tflint/issues/1790.

References

wyardley commented 2 months ago

With the lockfile, ignoring it might be the best bet, since it’s generated?

Thanks for the pointer. Would definitely love test support at some point if at all possible!