Open bcsgh opened 3 years ago
This tool helps with these exact issues: https://tfswitch.warrensbox.com
@skyzyx that looks like a nice tool for a somewhat related problem. However it seems to be focusing on a problem that is somewhat different in a few relevant ways.
required_version
as well as the local or remote tfstate and identify which available version will not alter the tfstate in non-backwards compatible ways. If having to know what version to use was acceptable, then installing multiple terrafrom binaries as terrafrom.$VER
would cover my use case. The docs do say that it can figure out required_version
in at least some cases, but that is only part of the problem. Furthermore, unless the information is coming from terraform it self or some other tool developed in concert with it, there will inevitably be fidelity issues in selecting an acceptable version.Practically, unless the solution is part of terraform it self, it's likely to come up short or outright fail on one or more of those points.
Also: this seems like a problem that the terraform product should provide a solution for.
Thanks for sharing this use-case, @bcsgh.
While we're talking about existing solutions, I will also point out tfenv
, which supports putting a .terraform-version
file in your project directory to specify which version you intend to use with it.
I've not used tfswitch before myself, but from referring to its documentation it seems like it has a similar capability with a .tfswitchrc
file.
While working on the dependency pinning problem in a recent release period I did start some research on this but ultimately concluded that it seems weird for Terraform CLI itself to be responsible for choosing which version of itself to run, because by the time Terraform CLI is running it's already, in a sense, "too late". However, I did consider making terraform init
detect a .terraform-version
file that seems to conflict with the current Terraform version and emit a warning, as a compromise to help folks who aren't using something like tfenv
to recognize when they've selected the wrong version, while letting tfenv
(or similar) make that automatic when installed.
I ended up not proceeding with that mainly because I ran out of research time and decided to focus only on provider dependency pinning for the first round, although now I see that tfswitch
exists and has its own .tfswitchrc
file and so if Terraform CLI were to start being aware of .terraform-version
it would in a sense be "playing favorites". With that said though, I think one potential way to start here would be to try to define a standard way to signal that a particular working directory is locked to a particular Terraform version, and then in the interim existing tools like tfenv
and tfswitch
could make use of that standard, with Terraform CLI itself potentially paying attention to it later if we can find a reasonable technical and UX design for it to do so.
Thanks for the commentary and background. I suspect this is one of those cases where most of the complexity is in correctly defining the problem, and very little in actually implementing it.
The "tool picking the correct version of it self" problem would be avoided if the solution is a separate tool that is just invoked the same way. If there was a standard pattern for installing multiple version of terraform (e.g. put them all in the same directory named terrafrom.$FULL_VERSION
) then it would be possible to make a tool (which would be put in the same directory and user could choose to name terraform
) that is build using the same version inspection logic that the different version of terraform uses and that just identifies and exec the right version.
As noted in a prior comment, there is nothing hard about that other than correctly identifying the version to run. (And doing that quickly.) Having both tools maintained by the same people would help avoid Hyrum's law kind of problems which would simplify and stabilize things a lot.
Hi @bcsgh! Thanks for those extra clarifications about your intent here.
I think what this ultimately comes down to is that there's only a limited amount of time we can practically spend working on fixes and improvements for Terraform, and so naturally we tend to prioritize spending time on problems not solved yet rather than problems that already have reasonable solutions, even if those reasonable solutions were built by others. We're grateful that folks in the community have spent the time building tools like tfenv
and tfswitch
, because they solve a real problem (which you identified well in this issue) and do so in a way that is mostly independent of what Terraform CLI itself does once run.
The divergence between .terraform-version
and .tfswitchrc
feels unfortunate to me here and so, as I was saying before, perhaps a practical short-term step here would be to encourage converging on a particular convention that Terraform CLI can therefore also have some straightforward awareness of. I'd love to hear from the tfenv
and tfswitch
maintainers about whether there are any practical concerns with that convergence, such as if tfenv
and tfswitch
are implementing slightly different behaviors that therefore benefit from their inputs being separated like this.
As you say, perhaps one day the Terraform team will also maintain a tool like this, but I want to be candid that it's unlikely that we'd prioritize such a thing in the short term simply due to the opportunity cost of doing so. My commentary here is aiming to find a compromise somewhere between these two extremes of doing nothing at all or creating an "official" single solution, so that we can try to make the existing answers work as well together with Terraform CLI as possible.
That you think this is something worth having, in some form, and are willing to leave this FR open as a placeholder for that desire is good enough for me. As to your priorities, they are yours to set. The only thing I can ask is that you continue to allow community interests to have some influence on the them.
Thanks.
I second that, but from a bit different angle:
Currently terraform system packages (deb/rpm/etc) are coming with latest version on and multiple versions can not coexist.
What I would suggest is to have separate packages for teraform-0.12, terraform-0.13 terraform-0.14 etc, providing virtual package terraform
and using update-alternatives
command to manage where the /usr/bin/terraform
points to.
(Yes, I know you can do this already, but it's error prone and not easy to work with.)
Use-cases
Multiple different sets of unconnected resources are managed using multiple different configurations by multiple different users and systems of automation. Upgrading the version of TF being used is not possible to do atomically across this whole ecosystem. Furthermore, at least some version steps happen automatically and irreversibly the first time a newer TF binary is used to act on a given configuration. Prevent that (and the resulting error when any non-upgraded installation then tries to look at it) necessitates a specific version pin in the configurations, which then requires that every user of that config have only that version installed, and that every configuration they use agree on the same version. ... Yuck.
Handling this would be made significantly simpler if the correct version of TF was automatically run.
Proposal
Provide a binary/wrapper/script that can inspect a TF config, check which version of terraform it is using and then lookup and invoke that version from the locally installed versions.
With this, the upgrade path would be: