$ terraform version
Terraform v0.13.5
+ provider registry.terraform.io/hashicorp/aws v3.12.0
+ provider registry.terraform.io/milosbackonja/1password v1.1.0
https://github.com/Tensho/terraform-issue-1password-provider
$ /script.sh
...
Error: Invalid resource type
on main.tf line 25, in output "check":
25: value = data.onepassword_item_login.abc.password
A data resource type "onepassword_item_login" is not supported by provider
"registry.terraform.io/hashicorp/1password".
Terrraform should infer the correct provider from the data source prefix name implicitly.
Terraform raises Error: Invalid resource type error.
Run:
$ ./script.sh
As you may note data source reference requires hashicorp/onepassword instead of milosbackonja/1password one. When I explicitly specify provider attribute on data source everything works fine.
I believe that the issue here is that the onepassword provider has been published by someone incorrectly to the registry as 1password. Terraform then is unable to automatically map resources or data sources with the onepassword_ prefix to this provider, even if given that local name.
Here's a similar diagnosis in the upstream provider repository. The only workarounds I can suggest are locally installing the provider, publishing the provider to the registry yourself under the correct onepassword name, or asking the upstream maintainer to do the same.
This doesn't appear to be a Terraform core bug, so I'm marking it "working as designed" and closing for now. Hopefully my explanation makes sense! Please let me know if anything is unclear.
@alisdair Thank you for the quick reply. But I wonder explicit version block doesn't mitigate this. I'd expect this mapping should make a deal:
terraform {
required_providers {
onepassword = {
source = "milosbackonja/1password"
version = "1.1.0"
}
}
}
It's odd to me Terraform relies on source attribute value (1password) over the key in required_providers (onepassword). Is it documented somewhere?
That's a good question! The intended behaviour is documented here:
Users of a provider can choose any local name for it. However, nearly every provider has a _preferred local name_, which it uses as a prefix for all of its resource types. (For example, resources from
hashicorp/awsall begin withaws, likeaws_instanceoraws_security_group.)Whenever possible, you should use a provider's preferred local name. This makes your configurations easier to understand, and lets you omit the
providermeta-argument from most of your resources. (If a resource doesn't specify which provider configuration to use, Terraform interprets the first word of the resource type as a local provider name.)
The last sentence contradicts my understanding of what was happening here, and so I'm going to reopen this issue and investigate further. Thanks!
I'm able to confirm this bug with 0.13.5 and 0.14 using the reproduction in the issue, so thanks again for that information. My analysis of the bug is below.
When loading the configuration with a resource which has no explicit provider argument, we determine which provider should be bound to the resource using the implied provider. This is derived from the resource type and the set of local provider names defined in required_providers:
https://github.com/hashicorp/terraform/blob/7c98be92c2423a3d2f777d0fac5359e7b11364f3/configs/module.go#L324-L327
https://github.com/hashicorp/terraform/blob/7c98be92c2423a3d2f777d0fac5359e7b11364f3/configs/module.go#L526-L534
In this case, this works: the onepassword_item_login data source is bound to the milosbackonja/1password provider, because you've specified the local provider name as onepassword.
Later, we statically validate resources against provider schemas. To look up the schema we do this:
https://github.com/hashicorp/terraform/blob/7c98be92c2423a3d2f777d0fac5359e7b11364f3/terraform/evaluate_valid.go#L215-L216
https://github.com/hashicorp/terraform/blob/7c98be92c2423a3d2f777d0fac5359e7b11364f3/configs/resource.go#L67-L72
This incorrectly returns the provider _type_ as a local name, which is normally correct. But not in this instance! Instead, it should be returning onepassword.
My first attempt to fix this would be to change the implementation of ProviderConfigAddr to defer to r.Addr().ImpliedProvider() for the case where there's no ProviderConfigRef. I'm not sure what knock-on effects that would have, but it would seem to make the method do what its documentation says it should.
Got it. I'm glad the current behavior doesn't seem odd to only me, TBH 🙂 Thanks again for the code walkthrough 🙇
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.
Most helpful comment
I'm able to confirm this bug with 0.13.5 and 0.14 using the reproduction in the issue, so thanks again for that information. My analysis of the bug is below.
When loading the configuration with a resource which has no explicit
providerargument, we determine which provider should be bound to the resource using the implied provider. This is derived from the resource type and the set of local provider names defined inrequired_providers:https://github.com/hashicorp/terraform/blob/7c98be92c2423a3d2f777d0fac5359e7b11364f3/configs/module.go#L324-L327
https://github.com/hashicorp/terraform/blob/7c98be92c2423a3d2f777d0fac5359e7b11364f3/configs/module.go#L526-L534
In this case, this works: the
onepassword_item_logindata source is bound to themilosbackonja/1passwordprovider, because you've specified the local provider name asonepassword.Later, we statically validate resources against provider schemas. To look up the schema we do this:
https://github.com/hashicorp/terraform/blob/7c98be92c2423a3d2f777d0fac5359e7b11364f3/terraform/evaluate_valid.go#L215-L216
https://github.com/hashicorp/terraform/blob/7c98be92c2423a3d2f777d0fac5359e7b11364f3/configs/resource.go#L67-L72
This incorrectly returns the provider _type_ as a local name, which is normally correct. But not in this instance! Instead, it should be returning
onepassword.My first attempt to fix this would be to change the implementation of
ProviderConfigAddrto defer tor.Addr().ImpliedProvider()for the case where there's noProviderConfigRef. I'm not sure what knock-on effects that would have, but it would seem to make the method do what its documentation says it should.