Azureで Terraform を使用するときの一般的な問題のトラブルシューティング

この記事では、Azureで Terraform を使用する場合の一般的な問題と考えられる解決策を示します。

Terraform に固有の問題が発生した場合は、 HashiCorp のコミュニティ サポート チャネルのいずれかを使用します。

HashiCorp Terraform 固有のサポート チャネル

プロバイダーの登録状態を一覧表示できない

エラー メッセージ:

エラー: プロバイダー登録の状態を一覧表示できません。 このエラーは、資格情報が無効であるか、サービス プリンシパルに Resource Manager API を使用するアクセス許可がないために発生する可能性があります。 Azure エラー: リソース。ProvidersClient#List: 要求への応答に失敗しました: StatusCode=403 -- 元のエラー: autorest/azure: サービスがエラーを返しました。 Status=403 Code="AuthorizationFailed" Message="オブジェクト ID '00000000-0000-0000-0000-000000000000' を持つクライアント '00000000-0000-0000-0000-000000000000' には、スコープ '/subscriptions/00000000-0000-0000-0000-000000000000' に対してアクション 'Microsoft.Resources/subscriptions/providers/read' を実行する権限がありません。または、スコープが無効です。" アクセス許可が最近付与された場合は、資格情報を更新します。"

背景:Cloud Shellから Terraform コマンドを実行し、特定の Terraform/Azure 環境変数を定義すると、競合が発生する可能性があります。 次の表に、環境変数と、それらが表すAzure値を示します。

環境変数 Azure の値
ARM_SUBSCRIPTION_ID Azure サブスクリプション ID
ARM_TENANT_ID Microsoft アカウントのテナント ID
ARM_CLIENT_ID Azure サービス プリンシパル アプリ ID
ARM_CLIENT_SECRET Azure サービス プリンシパルのパスワード

原因: この記述の時点で、Cloud Shellで実行される Terraform スクリプトは、現在のAzure サブスクリプションの値を使用して、ARM_SUBSCRIPTION_IDとARM_TENANT_ID環境変数を上書きします。 その結果、環境変数が参照するサービス プリンシパルに現在のAzure サブスクリプションに対する権限がない場合、Terraform 操作は失敗します。

状態ロックの取得中にエラーが発生しました

エラー メッセージ:

エラー: 状態ロックの取得中にエラーが発生しました。エラー メッセージ: 2 つのエラーが発生しました:
* state blob is already locked
* BLOB メタデータ "terraformlockid" が空でした
Terraform は、複数のユーザーが同時に状態を書き込むのを防ぎ、状態ロックを取得します。 上記の問題を解決して、もう一度やり直してください。 ほとんどのコマンドでは、"-lock=false" フラグを使用してロックを無効にできますが、これは推奨されません。

背景: Terraform 状態ファイルに対して Terraform コマンドを実行していて、このエラーが表示される唯一のメッセージである場合は、次の原因が適用される可能性があります。 このエラーは、ローカルおよびリモートの状態ファイルに適用されます。

原因: このエラーには、2 つの原因が考えられます。 最初の原因は、状態ファイルに対して Terraform コマンドが既に実行されており、ファイルに対してロックが強制されているため、何も壊れないことです。 2 つ目の原因は、コマンドの実行時に状態ファイルと CLI の間で接続の中断が発生した場合です。 この中断は、リモート状態ファイルを使用している場合に最も一般的に発生します。

解決策: まず、状態ファイルに対してコマンドをまだ実行していないことを確認します。 ローカル状態ファイルを使用している場合は、コマンドを実行しているターミナルがあるかどうかを確認します。 または、デプロイ パイプラインを調べて、実行中の何かが状態ファイルを使用しているかどうかを確認します。 この状態で問題が解決しない場合は、2 番目の原因によってエラーがトリガーされた可能性があります。 Azure Storage アカウント コンテナーに格納されているリモート状態ファイルの場合は、ファイルを見つけて、[リースの中断] ボタンを使用できます。

Azure Storage コンテナーの [リースの中断] ボタンを示すスクリーンショット。

他のバックエンドを使用して状態ファイルを格納する場合は、 推奨事項については、HashiCorp のドキュメントを参照してください。

VPN エラー

VPN エラーの解決については、 ハイブリッド VPN 接続のトラブルシューティングに関する記事を参照してください。

Terraform では、ストレージ アカウントの削除と再作成を計画しています

Terraform では、Azure が Terraform の外部でストレージ アカウントを変更した後、Azure ストレージ アカウントを削除して再作成することを計画する場合があります。 この動作は、サポートされているAzure Storage アカウント冗長変換中に発生する可能性があります。この変換では、account_replication_typeがゾーン以外のセット (LRS、GRS、RA-GRS) とゾーン セット (ZRS、GZRS、RA-GZRS) の境界を越えます。

プランを適用する前に、提案された変更を確認し、Terraform でストレージ アカウントの交換が必要と見なされる理由を確認します。 ストレージ アカウントを再作成すると、アプリケーションのダウンタイムやデータ損失が発生する可能性があります。

このリスクを軽減するには:

  • ストレージ アカウントを管理するデプロイの自動承認を無効にし、すべての terraform planを確認します。
  • ストレージ アカウント リソースのlifecycle ブロックでprevent_destroy = trueを構成します。
  • 変換を開始する前に、一時的に account_replication_type を ignore_changesに追加します。
  • 変換後、 terraform apply -refresh-only 実行して Terraform の状態を更新し、デプロイされたストレージ アカウントと一致するように Terraform 構成を更新します。
  • terraform planを実行し、予期しない変更が報告されていないことを確認した後にのみ、ignore_changesを削除します。

詳細な変換ガイダンスについては、ステートフルなAzure リソースの Terraform ドリフトの防止に関するページを参照してください。