My target is create internal library of modules. Modules should support two or more providers. So when developer wants to create for example compute instance he can just import module from library and use it on AWS or Azure or some other.
So far I haven’t find a way how to do this on module level. Only solution so far is
to create folder structure like:
modules/aws/instance/main.tf etc…
modules/azure/instance/main.tf etc
And then on actual configuration:
provider “aws” {
…
}
What you’re describing here is not a supported pattern in Terraform. Instead, the common way to do what you’re describing is like you tried already: implement multiple modules with similar variable and output blocks (thus ensuring they have a compatible interface) and then the calling module explicitly selects the required implementation, often then composing it with other modules that are compatible with any implementation.
This approach of course only works if the target vendors have similar enough offerings that you can define an abstraction over all of them. When implementing an approach like this, we’re normally thinking of higher-level abstractions like a kubernetes cluster, where there are many different ways to get one running but once they are running they all expose comparable functionality via the same API. I expect it would be difficult to define a useful abstraction over something as low-level as a single virtual machine instance, but depending on what you need from that abstraction it may be possible.
There’s more about this in the Module Composition section of the Terraform documentation, particularly in the section Multi-cloud Abstractions.