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.
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:
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.
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.
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.
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 requireshcl.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 thanhcl.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