-
Notifications
You must be signed in to change notification settings - Fork 9.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can't download a module on a registry for a provider with a hyphen -
in the name
#29532
Comments
Thanks for the report. I'm able to reproduce this, but I'm not sure it's a valid bug. What is happening here is Terraform is failing to parse the ambiguous source address as a Registry module, because the provider component is invalid. Because it's not a Registry source, we don't support a version constraint. The provider component of a module source address must consist only of alphanumeric characters—hyphens are not supported. I believe this constraint should also be enforced at the Terraform Registry side (including the Terraform Cloud private registry). The public registry has no such module available. It's unfortunate that the error message is obscure here, but that's a side effect of trying to parse ambiguous source addresses with best effort. What led you to try installing this module with provider |
Fixes hashicorp#29532 a hyphen can be present in provider name (except first and last character) in module URL to download from registry
In reality, I tried download a module on a private registry (with a Gitlab instance), with a custom provider which have a hyphen in his name. This provider will be made public shortly, but there are also other providers (no beta) which are already present with a hyphen. The module registry protocol allows to have a hyphen in the name of the provider but they do not exist on the Terraform registry because the procedure to publish a module on this Terraform registry requires to have a git repository in the format But with a third-party module registry implementation, a module with hyphen in provider's name is possible. In addition, it might be good to add a second method to add modules to the Terraform registry, for example with the format |
I happened to do some refactoring of the address-parsing codepaths recently and so I ended up reading back through the history of registry module address parsing and adding some notes in the code based on what I learned, which I'll summarize here in the hope it helps with thinking about what we might do in response to this issue. The most important quirk here is that Terraform v0.10 originally introduced the module registry syntax in a way that was ambiguous with previously-supported local file path syntax, and so it employed a model of first attempting to parse as a registry address and then falling back to a local file path if it encountered a syntax error. Terraform v0.12 partially resolved that by refining the rules for local paths to say that they must always start with either terraform/internal/addrs/module_source.go Lines 63 to 90 in cb5b159
As I noted in the comments here, this means that there's no path whereby a syntax error in registry address parsing can actually surface to the UI. Instead, it falls through to the external package address parser. If that parser fails then unfortunately we end up reporting its error, which is typically of much lower quality because The above explains why Terraform returns an unhelpful error in this situation, but it doesn't explain why the "remote system" portion of the address (what we previously called "provider", but never actually enforced it being a provider name in practice) has a more restrictive validation rule than the other two parts. In my earlier research I didn't actually arrive at a clear explanation for that, but I did still replicate the previous rules because my goal was to refactor the existing implementation rather than to change its behavior: terraform/internal/addrs/module_source.go Lines 292 to 315 in cb5b159
Re-reading this I think I actually made an error in the commentary I left here. Initially I had incorrectly implemented this to allow underscores, but tightened the regular expression after I saw it fail some existing unit tests. I guess I forgot to remove the statement about underscores from the comment at the time. If we were to relax the rules then this function would be the place to do it. I hope that (aside from the error I described above) the commentary here is useful in thinking through some of the implications of doing so. One particular concern is that it might cause existing modules containing legacy-style filesystem paths (which The final bit of context I want to capture here is that elsewhere in the Terraform language we typically assume providers will have local names consisting entirely of letters and digits (but don't require it, IIRC). For example, our behavior of automatically using the prefix of a resource type name to select its provider works by taking the position of the first underscore as the separator marking the end of the provider name, and so I would speculate (but have no evidence) that the current constraint on "remote system" names in module addresses was originally following the precedent that we required provider names to consist only of letters and digits, even though we've relaxed that into only a default assumption rather than a requirement in subsequent versions of the language. This of course says nothing specific about dashes, but I think that's just because idiomatic names within Terraform itself always use underscores to separate words, and the Terraform language permits dashes in identifiers only to make it easier to write configuration settings for remote systems that have different naming conventions. The In real-world modules I've seen a mix of two seemingly-equally-common patterns:
Of course, as I noted above we no longer consider the final portion of the registry module address format as directly a provider name, and instead leave it up to module developers to choose a suitable short descriptor for whatever remote system the module primarily works with. "Google beta" is the name of a provider rather than of a remote system, so it creates a rather awkward edge-case to the naming scheme: should a module using that provider just be classified as targeting "google", or is the fact that it's using the beta provider significant enough that it ought to be codified in the source address of the module? I don't have a strong opinion on the answer to this question right now; I think it'd be worth doing some research into how existing modules are being classified and what motivated those classifications. With all of this said, it does seem like our compatibility promises may be a practical blocker for any change to the registry module address syntax, and so we might find that the best we can do here is just document that requirement more explicitly in all of the relevant places, including in the module registry protocol documentation. Terraform is working as intended here, even though some of the rationale for those intentions is lost to history, and so I'm torn about whether to classify this as a documentation bug, which we would close by updating the documentation, or as an enhancement request which would represent us trying to find a backward-compatible way to permit more flexibility in "remote system" names. I do lean slightly towards the documentation bug angle here, because I don't really see a clear path to a backward-compatible language change, but I'm curious to hear if others have ideas about how we could approach this as an enhancement. |
A further thought that came to me after some time away for lunch: while we probably can't change the expected syntax of a registry module source address due to compatibility constraints, it's never been valid to use That would mean that the error message here would've been something like:
Since I knew that the current implementation would never actually show the error messages from the registry address parser, I didn't spend a lot of time polishing them. If we were going to do something like I've described here then it'd be good to also review the different error return paths to see if they're each generating a true and understandable error message. |
IMHO there's a bug here because the behavior is not the same if we're using the Terraform public registry or a private one. modules names with hypens (or underscores) are allowed on Terraform public registry but not on private ones. That being said, I understand well that there's no easy way out about this. |
Hi @BzSpi, The specific constraint about the target system consisting only of letters and digits is inside Terraform CLI itself and not something that should be able to vary between registries. Can you say a little more about what you've experienced, ideally including some reproduction steps, so we can understand how what you saw relates to the problem we've been discussing in this issue? Each implementation of the module registry protocol could potentially impose additional constraints on names beyond the ones Terraform CLI itself imposes, but if that is causing a problem then that would be something to fix in whatever registry is imposing the undesirable extra rules, rather than something to be fixed in Terraform CLI itself. |
I've implemented a private registry and have the exact same issue as mentioned by @jeremmfr . Here's an example: Terraform code
Terraform init sequence (with TF_LOG=trace)
With this source code (after republishing the module without hyphen in the registry), everything works fine:
I publish modules very often in the Terraform public registry and it' possible to have hyphen in the module names. Regarding what you said, it might be due to the fact that private registry has a domain name in their source and so, the parsing is not done the same way as the public registry. Hope this helps. |
My colleague @xp-1000 has kindly notified me that I was completely off topic here since my issue is about the name of the module and not the provider 😅 Sorry for the noise, I will look for a similar issue and update it or create a new one. |
@BzSpi, for your case, the source address of your module needs to be |
Indeed ... Double fail for me. |
Over in #30053 I've implemented the partial solution I described above of using the presence of the Assuming that changeset passes review and we merge it, that'll close out this issue for now. If we later devise a more precise solution then we can discuss that in a different issue, but since there isn't a ready design for that right now I'd like to move forward with this compromise for the foreseeable future, as a "better than nothing" answer. |
Following the discussion in hashicorp/terraform#29532, the documentation for module URLs in public or private registry is ambiguous because it's not the provider in URL but a "target system" and the restriction for characters is not the same as for the name of a provider
@apparentlymart I opened a PR hashicorp/terraform-website#1988 on terraform-website to clarify the "target system" in documentation. Can you review ? |
Hi @jeremmfr! Thanks for working on that. The Terraform Cloud documentation is outside of my typical scope, so I'll let the usual documentation authors be the ones to review that change, but for what it's worth it seems like a reasonable set of updates to me! Thanks again. |
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. |
Terraform Version
Terraform Configuration Files
Debug Output
https://gist.github.com/jeremmfr/2dfa73953adb30692106ed0b976549fe
Expected Behavior
Terraform try download the module on the registry.
Actual Behavior
Terraform stop with an error indicating that the module is not a registry URL.
This only appears when the provider has a hyphen
-
in the name.Steps to Reproduce
terraform init
Additional Context
The first problem encountered was on a private registry
but it is also present with public registry
The text was updated successfully, but these errors were encountered: