Reputation: 1095
Does anyone know if it is possible to have a Terraform script that uses multiple provider versions?
For example azurerm version 2.0.0 to create one resource, and 1.4.0 for another? I tried specifying the providers, as documented here: https://www.terraform.io/docs/configuration/providers.html
However it doesn't seem to work as it tries to resolve a single provider that fullfills both 1.4.0 and 2.0.0. It errors like:
No provider "azurerm" plugins meet the constraint "=1.4.0,=2.0.0".
I'm asking this because we have a large Terraform codebase and I would like to migrate bits by bits if doable.
There used to be a similar question raised, here: Terraform: How to install multiple versions of provider plugins? But it got no valid answer
Upvotes: 13
Views: 20030
Reputation: 338
This allowed us a smooth transition from helm2 to helm3, while enabling new deployments to use helm3 right away, therefore reducing the accumulation of tech debt.
Of course you can do the same for most providers
So the idea is to download a specific version of our provider (helm 0.10.6 in my case) and move it to one of the filesystem mirrors terraform uses by default. The key part is the renaming of our plugin binary. In the zip we can find terraform-provider-helm_v0.10.6
, but we rename it to terraform-provider-helm2_v0.10.6
PLUGIN_PATH=/usr/share/terraform/plugins/registry.terraform.io/hashicorp/helm2/0.10.6/linux_amd64
mkdir -p $PLUGIN_PATH
curl -sLo_ 'https://releases.hashicorp.com/terraform-provider-helm/0.10.6/terraform-provider-helm_0.10.6_linux_amd64.zip'
unzip -p _ 'terraform-provider-helm*' > ${PLUGIN_PATH}/terraform-provider-helm2_v0.10.6
rm _
chmod 755 ${PLUGIN_PATH}/terraform-provider-helm2_v0.10.6
We can use hashicorp/helm2
plugin from the filesystem mirror, and let terraform directly download the latest hashicorp/helm
provider, which uses helm3
terraform {
required_providers {
helm2 = {
source = "hashicorp/helm2"
}
helm = {
source = "hashicorp/helm"
version = ">= 2.0.0"
}
}
}
# you will find the doc here https://registry.terraform.io/providers/hashicorp/helm/0.10.6/docs
provider "helm2" {
install_tiller = false
namespace = "kube-system"
kubernetes {
...
}
}
# you will find the doc at latest version https://registry.terraform.io/providers/hashicorp/helm/latest/docs
provider "helm" {
kubernetes {
...
}
}
When initializing terraform, you will find that
- Finding latest version of hashicorp/helm...
- Finding latest version of hashicorp/helm2...
- Installing hashicorp/helm v2.0.2...
- Installed hashicorp/helm v2.0.2 (signed by HashiCorp)
- Installing hashicorp/helm2 v0.10.6...
- Installed hashicorp/helm2 v0.10.6 (unauthenticated)
Its pretty straightforward from this point. By default, helm resources will pick our updated helm provider at v2.0.2. You must explicitly use provider = helm2
for old resources (helm_repository
and helm_releases
in our case). Once migrated, you can remove it to use the default helm provider.
Upvotes: 6
Reputation: 29694
No you cannot do what you want. Terraform expects your constraint to match one plugin version as eluded to in:
If multiple versions of a plugin are installed, Terraform will use the newest version that meets the configuration's version constraints.
So your constraint cannot be parsed to match anyone plugin, hence the error
Upvotes: 0