要約:30秒で解決する方法
このエラーは、Terraform 0.13以降で、短い名前(awsなど)ではなく、完全な名前空間(hashicorp/awsなど)が必要になったために発生します。コードが正しく見えてもエラーが消えない場合は、ステートファイルがまだ古い形式を使用しています。解決するには、次のコマンドを実行してください。
terraform state replace-provider "registry.terraform.io/-/aws" "hashicorp/aws"
完了したら、terraform init を実行してすべてを同期させます。
なぜこのエラーが発生するのか
バージョン0.13より前、Terraformはいわば「閉じられた庭」のような状態でした。すべてのプロバイダーがHashiCorpから直接提供されていると想定されており、provider "aws" と記述するだけで動作していました。しかし、エコシステムが数千ものコミュニティプロバイダーへと拡大するにつれ、Terraformは公式Registry上の階層的な名前空間へと移行しました。
Invalid legacy provider address というメッセージは、Terraformが aws という名前のプロバイダーを見つけたものの、その所有者が誰であるか判断できないことを示しています。Terraformは一時的なプレースホルダーとして registry.terraform.io/-/aws を使用します。この「レガシー」なプロバイダーが、実際には公式の hashicorp/aws バージョンであることをTerraformに伝える必要があります。
移行を修正する3つの方法
1. コード内で明示的にプロバイダーを定義する
.tf ファイルで、プロバイダーをどこから取得するかをTerraformに正確に伝える必要があります。versions.tf または main.tf を開き、required_providers ブロックを追加してください。これは、3.xや4.xなどの特定のバージョンを使用している場合に特に重要です。
terraform {
required_version = ">= 0.13"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.0"
}
}
}
2. ステートファイル内のプロバイダーを再マッピングする
コードを修正しても、terraform.tfstate ファイルが古い名前を保持し続けている場合があります。何百ものリソースがあるプロジェクトでは、JSONを手動で編集したくないでしょう。代わりに、組み込みのCLIツールを使用してアドレスを入れ替えます。
使用しているプロバイダーに応じて、以下のコマンドを実行してください:
# AWSの場合
terraform state replace-provider "registry.terraform.io/-/aws" "hashicorp/aws"
# Azureの場合
terraform state replace-provider "registry.terraform.io/-/azurerm" "hashicorp/azurerm"
# Google Cloudの場合
terraform state replace-provider "registry.terraform.io/-/google" "hashicorp/google"
Terraformが変更内容を表示し、確認のために yes の入力を求めます。これにより、インフラストラクチャの内部的な「アドレス帳」が更新されます。
3. 自動アップグレードツールを使用する
まだ v0.13 のバイナリを使用している場合は、Terraformに面倒な作業を任せることができます。ルートディレクトリで以下を実行してください:
terraform 0.13upgrade
このツールは設定をスキャンし、必要な required_providers ブロックを自動的に生成します。複数のモジュールを含む複雑な環境では、大幅な時間の節約になります。
隠れたレガシー参照を探し出す
サードパーティのモジュールや terraform_remote_state データソースが古い命名規則を使用しているために、エラーが解消されないことがあります。標準的な修正方法で解決しない場合は、ステートファイルの中身を確認する必要があります。
ステートをローカルファイルにプルして調査します:
terraform state pull > my_infrastructure.json
ステートファイルは、時には5,000行を超える膨大なJSONになることがあります。内容を理解しやすくするために、私はよく YAML ↔ JSON コンバーター を使用します。複雑なJSONをYAMLに変換することで、provider: provider.aws を探しやすくなります。これが見つかった場合は、リソースがまだレガシーアドレスに紐付いていることを意味します。プロのヒント: 機密性の高いステートデータをサードパーティのサーバーに送信しないよう、ToolCraftのようなローカルまたはブラウザのみで動作するツールを使用してください。
修正を確認する方法
コマンドが完了したからといって、修正されたと思い込まないでください。次の3つのチェックを行ってください:
- 初期化:
terraform initを実行します。プロバイダーが完全なパスであるhashicorp/awsからダウンロードされるはずです。 - 検査:
terraform providersを実行します。ダッシュ(-)を含むエントリがないか確認してください。きれいなregistry.terraform.io/hashicorp/...パスが表示されているのが理想です。 - プラン:
terraform planを実行します。エラーが消え、「No changes. Your infrastructure matches the configuration」と表示されれば、移行は正式に完了です。
コマンドクイックリファレンス
目的
コマンド
設定を自動的に修正する
`terraform 0.13upgrade`
ステートを手動で更新する
`terraform state replace-provider [OLD] [NEW]`
すべてのプロバイダーを監査する
`terraform providers`

