Closed bowtie-ltsa closed 1 year ago
Hi @bowtie-ltsa, thanks for reporting this! It does look like the docs and the actual functionality disagree. I'm not sure if this is because the docs are wrong or if the functionality is wrong. I'll look into this further and try and decide which.
It does indeed seem like the implementation here is lacking a case to handle the use of the =
operator explicitly. If we are going to add support for that then we should be sure to support it both with and without a space after it, because both are valid and equivalent version constraint syntax.
There are a couple different ways we could make this more general within the API of the underlying version constraints package:
IntersectionSpec
that represents the version constraints, because getproviders.VersionConstraints
is just an alias to that type. I guess the rule would be to check if there's exactly one selection spec, its operator is OpEqual
, and its boundary is equal to the selected version.versions
package's MeetingConstraints
function and then test whether the requested version is in the resulting version set. MeetingConstraints
has its own rule that prerelease versions are only available when selected exactly, so our caller could potentially just ask this constraints set about all of the versions and let the versions
package be the one to filter out the prerelease versions when it's appropriate to do so.I think the reason for this quirk is that a while back now we adopted a different library for wrangling version and version constraint strings, because the hashicorp/go-version
one tends to generate poor error messages for invalid input and doesn't expose enough information for our installers to do their work. The provider installer uses the new library exclusively, but it's been longer since we did any significant work on the module installer and so it's still largely using hashicorp/go-version
to do its work. However, this logic is mixing a version value using the old library with a version constraint using the new library, and so it's relying on string comparison to make this decision rather than using the MeetingConstraints
API which already knows how to implement this properly.
The documentation about version constraints is trying to discuss both provider version constraints and module version constraints together, and is therefore assuming that they both behave the same way. I believe the quoted sentence is true for provider version constraints because they exclusively use the new versions library, but the module version constraint handling is currently a bit of a hack and so it's not implementing the behavior quite as specified.
I think option 2 above is the better choice if it's practical to use it, because it matches how the provider installer does similar things. The current mixing of the two different libraries for version wrangling might complicate things however. I would recommend against a broad rework of how the module installer deals with versions just to fix this bug -- I think better to amortize that risk with other possible modernizations of the module installer -- but perhaps there's a more localized way to deal with it.
I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.
Terraform Version
Terraform Configuration Files
Debug Output
https://gist.github.com/bowtie-ltsa/cb1ef0658cea1433e90531ab0472c066
Expected Behavior
the requested version should have been downloaded, according to my understanding of the docs
https://developer.hashicorp.com/terraform/language/expressions/version-constraints#version-constraint-behavior
Actual Behavior
actual behavior
Error: Unresolvable module version constraint
workaround:
to work-around this problem, you can remove the exact version operator (=) from the version attribute string --
this fails:
this works:
proposed fix
change this line? https://github.com/hashicorp/terraform/blob/main/internal/initwd/module_install.go#L390 Because it is looking for an exact string match, ignoring the "=" operator that may be the first character of the version constraint. Right?
Steps to Reproduce
👉 just run
terraform init
with the above terraform, but to be more precise:Additional Context
none. I reproduced this in an isolated simple container.
References
No response