Multiple provider use cases in Terraform
Last days I'm heavily working on the automation of our cloud infrastructure onboarding processes and I had the need to work with multiple providers at once. I didn't find an article with complex overview of the possibilities and things to be considered when you'd like to work with multiple providers at once, so here it is.
Providers allow Terraform to communicate with the APIs of managed services. Some of them require specific configuration and you can easily meet conditions where usage of multiple providers in your terraform templates or modules is required.
It doesn't matter if you need to use various providers or various configuration of the same provider in this article I'll cover both scenarios from basic implementation to more complex ones.
At the moment Terraform public registry contains 1699 providers which you can use. You can create your custom public or private provider as well, but I'll cover this topic in one of the further articles. Usage of techniques described in this article for your IaC implementation will be still same, it doesn't matter if it will be your custom or third party, public or private provider…
Various providers in a single instance
For this use case we need to create a resource group in Azure and create workspace for Terraform state file in Terraform Cloud. Basically for this scenario we need to have following AzureRM Resource Group and TFE Workspace resources defined.
To make it work we just need to do some additional stuff in our code and Terraform will natively take care about it. So let's extend our previous snippet into the full deployment example.
Pretty simple, isn't it? So, let's make it little bit more complicated and extend our use case by wrapping the resources which we would like to create under the child module and we will use in our further implementation.
Usage with child module
Let's assume that we have created the Terraform module where the same resources as in previous example will be created. In order to achieve goal of this scenario we have to define module like following code snippet.
Once we have created the module we can do the implementation in a following way. Be aware of using child modules with multiple providers as single instances and do not define provider block inside the module templates. This could lead to unexpected behavior.
Various providers in multiple instances
Let's return back to our first scenario and extend the requirements of resources deployment by amount, but let's deploy Azure resources to two different subscriptions and Terraform cloud workspaces to two different Terraform Cloud organizations. To be able to achieve it we have to do following enhancements in the resources creation.
Still looks simple? Let's have a look on the second scenario with child module and extend the scenario requirements is a similar way like in the previous one. Here I'd like to point out usage of configuration aliases inside the required providers block. Usage of this approach is strongly recommended. Let's have a look on the module template.
As you can see except the duplication of resources to be created, only configuration aliases need to be added into the required providers block.
So how the final implementation scenario look like? Let me show the last but not least example of this article, where we will pass providers explicitly to the child module.
Conclusion
- If your are using child modules with multiple providers by default, ie. single instance do not use provider block inside the module templates.
- Provider without the alias argument is considered as default and don't need to be passed to the resource or declared within module definition.
- Provider configuration belong to the root module of Terraform declaration. — Implicit provider inheritance should be used only when single instance of provider is used in a module .
- Providers inheritance to child modules should be done via module Meta arguments.
- To define multiple configurations of module providers, configuration aliases argument should be used inside required providers block.
- When multiple configurations of module providers are declared, module needs to consume providers explicitly as is described here.