tfutils / tfenv

Terraform version manager
MIT License
4.43k stars 450 forks source link

tfenv does not resolve `terraform { required_version = "1.2.8" }` block from tf file #360

Open mwos-sl opened 1 year ago

mwos-sl commented 1 year ago

As far as I understand, .terraform-version file is not needed as long as I've got:

terraform { 
  required_version = "1.2.8"
 }

configured in one of my tf files, which I do have. Yet it seems tfenv is not resolve that:

tfenv version-name
cat: /usr/local/Cellar/tfenv/3.0.0/version: No such file or directory
Version could not be resolved (set by /usr/local/Cellar/tfenv/3.0.0/version or tfenv use <version>)
▶ tfenv list
  1.2.8
  1.0.7
▶ tfenv --version
tfenv 3.0.0

It starts working when I add .terraform-version, but I'd prefer to not have a duplicated place for pointing to terraform version.

mwos-sl commented 1 year ago

Maybe related: https://github.com/tfutils/tfenv/issues/261

tpoindessous commented 1 year ago

Hi @mwos-sl !

You need to set a shell variable if you want tfenv to auto switch to the right version without having to type tfenv install.

My example :

My terraform.tf file

terraform {
  required_version = "1.0.3"
}

I don't have a global version installed :

$ terraform --version
Version could not be resolved (set by /opt/homebrew/Cellar/tfenv/3.0.0/version or tfenv use <version>)
$ tfenv version-name
Version could not be resolved (set by /opt/homebrew/Cellar/tfenv/3.0.0/version or tfenv use <version>)
$ tfenv use min-required
Switching default version to v1.0.3
Default version (when not overridden by .terraform-version or TFENV_TERRAFORM_VERSION) is now: 1.0.3
$ tfenv version-name
1.0.3

With a shell variable, I can do this :

# resetting to an old version for the test
$ tfenv use 1.0.2
$ terraform -version
Terraform v1.0.2
$ tfenv version-name
1.0.2
$ export TFENV_TERRAFORM_VERSION=min-required
$ tfenv version-name
1.0.3
$ terraform -version
Terraform v1.0.3

Hopes that will help you !

Have a nice day !

Zordrak commented 1 year ago

@mwos-sl - seems like a complete explanation from @tpoindessous . Does this resolve your situation?

jmnavarrol commented 1 year ago

I think I need a bit of clarification here.

As per tfenv's README it doesn't seem it parses terraform sources to find a proper version to install, that is, it does not honor

terraform {
  required_version = "x.y.z"
}

Am I wrong?

jmnavarrol commented 1 year ago

More info: I read more carefully and I noticed the combination of TFENV_AUTO_INSTALL=true + TFENV_TERRAFORM_VERSION=[something] and I did some more tests (TFENV_AUTO_INSTALL is not defined, therefore it goes with its default to true).

My main.tf file has this:

terraform {
  required_version = "= 1.2.6"

  required_providers {
    local = "= 2.2.3"
  }
}
  1. This works: export TFENV_TERRAFORM_VERSION=min-required
    version '1.2.6' is not installed (set by TFENV_TERRAFORM_VERSION). Installing now as TFENV_AUTO_INSTALL==true
    Installing Terraform v1.2.6
    Downloading release tarball from https://releases.hashicorp.com/terraform/1.2.6/terraform_1.2.6_linux_amd64.zip
    [...]
  2. This does NOT work: export TFENV_TERRAFORM_VERSION=latest-allowed
    version '1.3.4' is not installed (set by TFENV_TERRAFORM_VERSION). Installing now as TFENV_AUTO_INSTALL==true
    No versions matching 'latest-allowed' found in remote
    /(...)/tfenv/lib/tfenv-exec.sh: línea 43: /(...)/tfenv/versions/1.3.4/terraform:
      No such file or directory

    Given my version constrain above, I expected for both min-required and latest-allowed to render the same result: both should install and activate terraform version 1.2.6.

I also created #367 since, IMHO, the expectation coming from TFENV_AUTO_INSTALL=true is for tfenv to "try its best" to end up with a running terraform environment.

For this to happen, in the case of this issue, no other environment variable or hinting file should be needed: tfenv should discover the constrain declared within terraform code itself and honor it (with a default to either an already installed terraform version, or the most up-to-date one that complies with the requirement, akin, I'd say, to what i.e. pip would do with python eggs).