Closed jcarlson closed 1 year ago
That's a https://github.com/tfutils/tfenv bug. Please open the issue to them.
tfenv
should check the version recursively starting from dir when it found .terraform-version
.
But not higher than closest .git
dir exist, I suppose
Respectfully, I do not believe this to be a bug in tfenv
.
When this plugin runs, it changes the current working directory successively to each sub-directory of the repository with changed files before running terraform fmt
. From the context of a sub-directory, tfenv
has no way of knowing what the correct version of Terraform to use should be, because the Terraform version is specified in the configuration root.
Even if tfenv
were able to successfully install 0.14.0
(and I can resolve that issue), the next issue is that this plugin is then formatting each sub-directory with a different version of Terraform than the root. In my example above, the root
gets formatted with Terraform 1.4.4, while the modules/sub
directory would get formatted with Terraform 0.14.0.
At the very least, this plugin should use a consistent version of Terraform throughout.
In my opinion, this plugin should not change working directory into each sub-directory containing changed files, but instead pass as arguments to terraform fmt
the name of each file that has changed and run using the repository's root as the working directory.
Even if tfenv were able to successfully install 0.14.0 (and I can resolve that issue), the next issue is that this plugin is then formatting each sub-directory with a different version of Terraform than the root. In my example above, the root gets formatted with Terraform 1.4.4, while the modules/sub directory would get formatted with Terraform 0.14.0.
As I said above, tfenv
should try find .terraform-version
by next algorithm:
.terraform-version
2.1. If .terraform-version
is founded - check for TF version recursively from dir where .terraform-version
founded
2.2 If after checking parent dirs in git repo .terraform-version
is still not found - go to step 3..terraform-version
- tfenv
should use that config and recursively apply it from git repo rootYes, tfenv
does all those things as described. In my example configuration above, tfenv
finds the .terraform-version
at the repo root, but the .terraform-version
is specified as min-required
.
When tfenv
is instructed to resolve min-required
, it looks at the required_version
inside the terraform
block of the current working directory, which tfenv
would reasonably assume to be the Terraform configuration root.
In my example configuration, the terraform
block in the project root specifies 1.4.4
, and this is the version we want to use. This works correctly when you run terraform fmt
from the configuration root.
The problem occurs when you change directories into the included sub-module. This is no longer the configuration root, and this included module does not specify an exact version of Terraform, but rather, a minimum viable version of Terraform that the current module is compatible with.
So from the repo root, tfenv
sees min-required
, which means 1.4.4
.
But if you cd modules/sub
and then run terraform version
, tfenv
now sees min-required
and from the modules/sub
directory, that is >= 0.14
, which is why tfenv
is trying to use 0.14.
So from that point of view, this issue doesn’t really have anything to do with terraform_fmt
at all, since we can reproduce this issue without using pre-commit
at all.
What I am suggesting here is that perhaps the terraform_fmt
script should keep the working directory as the repository root, or at least expose a configuration option to make it so, so that tfenv
version resolution works based off the Terraform root configuration, and not an arbitrary sub-directory in the repository.
When tfenv is instructed to resolve min-required, it looks at the required_version inside the terraform block of the current working directory, which tfenv would reasonably assume to be the Terraform configuration root.
Step 2.1.
What are you suggesting needs to be changed about my sample configuration above in order to work properly?
What I am suggesting here is that perhaps the terraform_fmt script should keep the working directory as the repository root, or at least expose a configuration option to make it so, so that tfenv version resolution works based off the Terraform root configuration, and not an arbitrary sub-directory in the repository.
Okay, let's imagine that tfenv
works correctly (which is not), and there is some problem here in pre-commit-terraform hooks logic.
Firstly, did you see the hooks code? You propose or change how works mostly all hooks here:
Or make terraform_fmt
maintained completely separate with different logic.
Also, tfenv
could affect mostly all terraform hooks, which somehow use terraform, IE, these two, which return us to option 1 (which will not work correctly out of the box, because some hooks required to be inside dir)
What are you suggesting needs to be changed about my sample configuration above in order to work properly?
Open bug report to tflint
and pin version in another way:
main.tf
terraform {
required_version = "~> 1.0"
}
.terraform-version
1.4.4
Hmm, that could not work too, please check. No idea, don't use tfenv
, I prefer asdf
, which has no problems at all
Describe the bug
tfenv
allows for the use ofmin-required
as the version specified in a project's.terraform-version
file, which then parses the Terraformrequired_version
from the configuration files.The
terraform_fmt
hook runsterraform fmt
using the directory of the changed file as the working directory, rather than the repository root as the working directory.In a configuration that includes sub-modules as sub-directories, where that sub-module requires a different, less-restrictive version of Terraform, the
terraform_fmt
hook then attempts to install the wrong version of Terraform by installing the minimum version for that sub-module, rather than the version for that project.For example, I have a root configuration that uses Terraform 1.4.4, and a sub-module which requires Terraform
>= 0.14
, which 1.4.4 satisfies. However, when files in the sub-module change,terraform_fmt
failed becausetfenv
is attempting to install Terraform 0.14, and on my M1 Apple Silicon Mac, this fails, since there is no ARM build of Terraform 0.14.How can we reproduce it?
Observe the following sample configuration:
main.tf
modules/sub/main.tf
The repository root also includes the following files:
.terraform-version
.pre-commit-config.yaml
With the above configuration in a clean git working tree:
The following error is produced:
Environment information
uname -a
output:.pre-commit-config.yaml
Proposed Solution
The
terraform_fmt
hook appears to receive an array of files which have changed and should be formatted. Instead of dropping into each containing directory to runterraform fmt
, runterraform fmt
from the repository root and pass the relative path of each file as an argument toterraform fmt
.For example, do this:
And not:
This will allow
tfenv
to detect the Terraformrequired_version
specified at the root instead of in themodules/sub
module.