💡

同じプロバイダーで複数バージョンを利用する

2025/04/03に公開

同じプロバイダーで複数バージョン(複数と言えど実際は 2 つまで)を使いたいという特殊なケースに対応させた。
あんまりやらないほうがいいとは思うものの、こういう回避方法もあるよということでメモがてら書いておく。

背景

今回のケースでは、 cloudflare provider を v4 から v5 に上げたかった。
しかし v5(現時点での最新バージョンは v5.2.0) では利用しているリソースの一部にクリティカルなバグがあり完全なアップグレードができないことがわかった。
私の環境で使用しているリソースの 9 割方は v5 に対応できるため、 1 割なら複数バージョンを同居させるかという判断をした。触る人も限られているし、バグが修正されたら v5 にあげる方針。

失敗ケース

愚直に provider を 2 つ書いてみる。
terraform init してみると cloudflare/cloudflare というプロバイダーは一回しか書けないよというエラーで失敗する。

provider.tf
terraform {
  required_providers {
    cloudflare = {
      source  = "registry.terraform.io/cloudflare/cloudflare"
      version = "5.2.0"
    }
    cloudflare-v4 = {
      source  = "registry.terraform.io/cloudflare/cloudflare"
      version = "4.52.0"
    }
  }
  backend "local" {
    path = "local.tfstate"
  }
}

provider "cloudflare" {
  api_token = "xxxxxx"
}

provider "cloudflare-v4" {
  api_token = "xxxxxx"
}
terraform init
Initializing the backend...
Initializing provider plugins...
- Reusing previous version of cloudflare/cloudflare from the dependency lock file
╷
│ Warning: Duplicate required provider
│ 
│   on provider.tf line 3, in terraform:
│    3:     cloudflare = {4:       source  = "registry.terraform.io/cloudflare/cloudflare"5:       version = "5.2.0"6:     }
│ 
│ Provider cloudflare/cloudflare with the local name "cloudflare" was previously required as "cloudflare-v4". A provider can only be required once within required_providers.
╵
╷
│ Error: Failed to query available provider packages
│ 
│ Could not retrieve the list of available versions for provider cloudflare/cloudflare: locked provider registry.terraform.io/cloudflare/cloudflare 5.2.0 does not match configured version constraint 4.52.0,
│ 5.2.0; must use terraform init -upgrade to allow selection of new versions
│ 
│ To see which modules are currently depending on cloudflare/cloudflare and what versions are specified, run the following command:
│     terraform providers
╵
terraform providers
Providers required by configuration:
.
└── provider[registry.terraform.io/cloudflare/cloudflare] 4.52.0, 5.2.0

Providers required by state:

    provider[registry.terraform.io/cloudflare/cloudflare]

╷
│ Warning: Duplicate required provider
│ 
│   on dev_provider.tf line 7, in terraform:
│    7:     cloudflare-v4 = {8:       source  = "registry.terraform.io/cloudflare/cloudflare"9:       version = "4.52.0"10:     }
│ 
│ Provider cloudflare/cloudflare with the local name "cloudflare-v4" was previously required as "cloudflare". A provider can only be required once within required_providers.
╵

成功ケース

そういえば公式のプロバイダーは Terraform RegistryOpenTofu Registry にあることに気がついたので、それぞれを source にしてやればうまくいくんじゃないかと思ってやってみたら、うまくいった。
※ OpenTofu Registry を公式と呼んで良いのかはわからない。

provider.tf
terraform {
  required_providers {
    cloudflare = {
      source  = "registry.terraform.io/cloudflare/cloudflare"
      version = "5.2.0"
    }
    cloudflare-v4 = {
      source  = "registry.opentofu.org/cloudflare/cloudflare"
      version = "4.52.0"
    }
  }
  backend "local" {
    path = "local.tfstate"
  }
}

provider "cloudflare" {
  api_token = "xxxxxx"
}

provider "cloudflare-v4" {
  api_token = "xxxxxx"
}
terraform init
Initializing the backend...
Initializing provider plugins...
- Reusing previous version of cloudflare/cloudflare from the dependency lock file
- Finding registry.opentofu.org/cloudflare/cloudflare versions matching "4.52.0"...
- Using previously-installed cloudflare/cloudflare v5.2.0
- Installing registry.opentofu.org/cloudflare/cloudflare v4.52.0...
- Installed registry.opentofu.org/cloudflare/cloudflare v4.52.0 (self-signed, key ID C76001609EE3B136)
Partner and community providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:
https://www.terraform.io/docs/cli/plugins/signing.html
Terraform has made some changes to the provider dependency selections recorded
in the .terraform.lock.hcl file. Review those changes and commit them to your
version control system if they represent changes you intended to make.

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

その他のケース(未検証)

公式プロバイダーとは別にローカルへ公式プロバイダーをダウンロードしてきてカスタムプロバイダーとして使う方法。
成功ケースはこれ[1]を参考にしている。
ただ、弊環境では HCP Terraform を利用している(サンプルコードはローカルで検証している)ため、ダウンロードしてきたカスタムプロバイダーの運用を考える必要も出てきて、めんどいなと思ってやめた。

脚注
  1. How to use multiple versions of the same provider in Terraform (it's a terrible idea) ↩︎

Discussion