-
Notifications
You must be signed in to change notification settings - Fork 376
Description
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: #1912 terraform-linters/tflint-ruleset-terraform#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:
Lines 73 to 81 in 0b06266
// GetFile returns the hcl.File based on passed the file name. | |
func (s *GRPCServer) GetFile(name string) (*hcl.File, error) { | |
// Considering that autofix has been applied, prioritize returning the value of runner.Files(). | |
if file, exists := s.runner.Files()[name]; exists { | |
return file, nil | |
} | |
// If the file is not found in the current module, it may be in other modules (e.g. root module). | |
return s.files[name], nil | |
} |
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.
Lines 219 to 221 in 0b06266
// ApplyChanges applies the autofix changes to the runner. | |
func (s *GRPCServer) ApplyChanges(changes map[string][]byte) error { | |
diags := s.runner.ApplyChanges(changes) |
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 terraform-linters/tflint-ruleset-terraform#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 #1790.
References
- Run tflint on *.hcl files #1912
- Remove unused values in tfvars tflint-ruleset-terraform#151
- https://github.com/terraform-linters/tflint/blob/v0.50.0/plugin/server.go#L73-L81
- https://github.com/terraform-linters/tflint/blob/v0.50.0/plugin/server.go#L219-L221
- Errors with no range cannot be identified when emitted in recursive mode #1790
- https://github.com/terraform-linters/tflint-plugin-sdk/blob/v0.18.0/tflint/interface.go#L80-L252