azd downのCIハングを解消|Terraformバックエンド初期化と–forceの正しい使い方

Terraformを利用するAzure Developer CLIのCI/CDで、azd down --no-promptが終わらない、または新しいエージェントで「backend initialization required」が発生する場合は、PR #9143を含むazd 1.28.1以降へ更新してください。2026年7月ロールアップ時点では、1.29.0以降へ更新すれば修正を利用できます。(GitHub)

ただし、重要な注意点があります。修正後のazd down --no-promptは、Terraformリソースを無条件に削除するコマンドではありません。--forceを付けない場合は削除予定をプレビューして終了し、実際に削除する場合はazd down --no-prompt --forceを実行します。 また、fresh agentでは削除処理の前にTerraformバックエンドが非対話モードで初期化されるようになりました。(GitHub)

目次

結論:azd 1.28.1以上へ更新し、目的に応じて–forceを使い分ける

今回の問題に対する実務上の対応は、次の3点です。

目的実行コマンド修正後の動作
ローカル端末で確認して削除するazd downTerraformの確認プロンプトを表示
CIで削除内容だけ確認するazd down --no-promptTerraformバックエンドを初期化し、削除プランを表示して終了
CIで実際に削除するazd down --no-prompt --forceTerraformバックエンドを初期化し、自動承認付きで削除

直接の修正が最初に含まれたのは、2026年7月22日リリースのazd 1.28.1です。2026年7月ロールアップでは1.29.0までの変更として紹介されているため、特別な理由がなければ1.29.0以上へ更新するのが分かりやすい対応です。(GitHub)

CIのazd down –no-promptがハングしていた原因

Terraformの確認入力を待ち続けていた

Terraformのdestroyは、通常、リソースを削除する前に確認入力を求めます。

従来のazdでは、azd down --no-promptを実行しても、Terraform側には自動承認を指定せず、通常のterraform destroy相当の処理が呼び出されるケースがありました。

ローカル端末であれば、ユーザーが確認プロンプトに回答できます。しかし、CI/CDジョブには対話用のTTYがないため、Terraformは標準入力からの回答を待ち続けます。その結果、エラーで終了するのではなく、パイプラインが止まったように見える状態になっていました。(GitHub)

この問題では、次のような症状が発生します。

  • azd down --no-promptのログが途中で止まる
  • ジョブがタイムアウトするまで終了しない
  • CPU使用率などに異常はない
  • --forceを付けると処理が進む
  • 手動で入力できる端末では再現しない

つまり、Terraformの処理が遅いのではなく、見えない確認プロンプトへの入力待ちが原因でした。

fresh agentではTerraformバックエンドも初期化されていなかった

もう一つの問題は、エフェメラルなCIエージェントや新しく作成されたセルフホステッドエージェントで、Terraformの初期化情報が存在しないことです。

fresh agentには通常、前回のジョブで生成された.terraformディレクトリなどがありません。その状態でazd down --forceを直接実行すると、Terraformバックエンドが初期化されていないため、次のようなエラーが発生することがありました。

backend initialization required

従来は回避策として、削除前にazd provision --previewなどを実行し、間接的にterraform initを済ませる運用が使われることもありました。しかし、リソースを削除したいだけなのにプロビジョニング系コマンドを先に実行するため、処理の意図が分かりにくくなります。(GitHub)

PR #9143で修正された動作

PR #9143では、CI/CD環境または--no-prompt指定時を非対話実行として判定し、Terraformの削除処理を次のように変更しています。(GitHub)

非対話実行ではterraform initを先に行う

CI/CDまたは--no-promptでTerraformを削除する場合、azdは先に次の処理に相当するバックエンド初期化を行います。

terraform init -input=false

これにより、新しいエージェントに.terraformディレクトリがなくても、リモートバックエンドの設定を読み込み、削除プレビューまたは削除処理を開始できます。

削除時の初期化では-upgradeを付けない実装になっています。これは、削除するだけの処理でプロバイダーやモジュールのバージョンを更新し、.terraform.lock.hclの内容を意図せず変えることを避けるためです。

–forceなしでは削除プレビューだけを実行する

非対話環境で--forceを付けずに実行した場合は、Terraformの確認プロンプトを表示する代わりに、destroy planを表示します。

azd down --no-prompt

このコマンドは、削除される予定のリソースを確認するためのものです。実際のリソースは削除せず、処理は正常終了します。

PR #9143の最終仕様では、次の流れになります。

  1. Terraformバックエンドを非対話モードで初期化する
  2. destroy planを生成する
  3. 削除予定の内容を出力する
  4. リソースを削除せずに終了する
  5. --forceを付けて再実行するよう案内する

CIで削除前レビューを行いたい場合に、そのまま利用できる動作です。(GitHub)

–forceありでは自動承認付きで削除する

実際にリソースを削除する場合は、--forceを付けます。

azd down --no-prompt --force

この場合、Terraformには-auto-approveが渡され、確認入力なしで削除処理が進みます。

terraform destroy -auto-approve

バックエンドの初期化も先に行われるため、fresh agentでも、バックエンド設定や認証に問題がなければ削除処理を開始できます。

「非対話モードでdestroyを自動承認」の読み違いに注意

2026年7月ロールアップとazd 1.28.1のリリースノートでは、今回の修正が「非対話実行時にdestroyを自動承認する」という趣旨で簡潔に説明されています。(Microsoft for Developers)

しかし、PR #9143の最終説明、azd downのヘルプ、1.28.1タグの実装を確認すると、実際の動作は次のように分かれています。

  • --no-promptのみ:削除プレビューを表示し、削除せずに終了
  • --forceあり:-auto-approveを付けて実際に削除

したがって、--no-promptは削除への同意を意味しません。

--no-promptは「対話入力を要求しない」という指定であり、--forceが「確認なしで削除を実行する」という指定です。CIスクリプトを修正する際は、この2つを混同しないことが重要です。(GitHub)

azdを修正版へ更新する手順

現在のバージョンを確認する

最初に、CIエージェントとローカル端末の両方でazdのバージョンを確認します。

azd version

出力されたバージョンが1.28.0以前であれば、PR #9143の修正は含まれていません。最低でも1.28.1、2026年7月ロールアップを基準にするなら1.29.0以上へ更新します。(GitHub)

azd updateで更新する

azdには、インストール元を検出して適切な更新方法を呼び出すazd updateコマンドがあります。

azd update
azd version

azd updateはBeta機能です。安定したCI環境では、毎回最新版へ更新するよりも、CIイメージやセットアップ処理で修正版以上のバージョンを明示的に使用する方が、再現性を確保しやすくなります。(Microsoft Learn)

インストール方法別の更新コマンド

azd updateを使用しない場合は、最初にazdを導入した方法と同じ方法で更新します。

環境更新コマンド
Windows/wingetwinget upgrade microsoft.azd
Windows/Chocolateychoco upgrade azd
macOS/Homebrewbrew upgrade --cask azure/azd/azd
Linux・macOS/インストールスクリプトcurl -fsSL https://aka.ms/install-azd.sh | bash
Windows/インストールスクリプトpowershell -ex AllSigned -c "Invoke-RestMethod 'https://aka.ms/install-azd.ps1' | Invoke-Expression"

更新後は、必ずもう一度azd versionを実行してください。公式ドキュメントでも、バージョン確認にはazd versionを使用する手順が案内されています。(Microsoft Learn)

CIエージェント上の古いazdにも注意する

ローカルPCだけを更新しても、CIエージェントに古いazdが残っていれば問題は解消しません。

CIジョブの冒頭に、次の確認を入れておくと原因を切り分けやすくなります。

azd version
command -v azd

Windowsエージェントでは、次のように確認できます。

azd version
where.exe azd

複数の方法でazdをインストールしていると、新しいバイナリを導入しても、PATH上では古いazdが優先されることがあります。

特に確認したいのは次の箇所です。

  • CIのベースイメージ
  • ツールキャッシュ
  • セルフホステッドエージェントに残った旧バージョン
  • コンテナーイメージ内のazd
  • PATHに登録された複数のazd
  • CIテンプレートで固定されているバージョン

CIでazd downを実行する正しいパターン

削除内容を確認するジョブ

削除予定のリソースだけを確認する場合は、--forceを付けません。

set -euo pipefail

azd version
azd down --no-prompt

修正版では、このジョブはTerraformバックエンドを初期化し、削除プランを表示したあと、リソースを削除せずに正常終了します。(GitHub)

ここで注意したいのは、終了コード0でもリソースは削除されていないことです。

パイプラインが終了コードだけを見て「環境削除済み」と判定している場合、誤った後続処理が実行される可能性があります。プレビュー用ジョブと本番削除用ジョブは、明確に分けてください。

実際に削除するジョブ

承認後にリソースを削除するジョブでは、--forceを付けます。

set -euo pipefail

azd version
azd down --no-prompt --force

このコマンドは確認なしでAzureリソースを削除します。実行前に、対象のazd環境、Azureサブスクリプション、リソースグループ、Terraformバックエンドが正しいことを確認してください。

推奨するパイプライン構成

安全性と自動化を両立させるなら、次のように段階を分けます。

  1. azd down --no-promptで削除プランを生成する
  2. プランのログまたは成果物を確認する
  3. CI/CDの承認ゲートを通す
  4. 同じコミットとazd環境を使ってazd down --no-prompt --forceを実行する
  5. Azure側でリソースの削除結果を確認する

プレビューと削除の間でTerraformコード、変数、対象環境が変わると、確認した内容と実際の削除内容が一致しなくなります。両方のジョブで、同じコミット、同じ環境名、同じバックエンドを使用することが重要です。

azd 1.29.0ではCI環境の自動検出も強化された

azd 1.29.0では、CI/CD環境やAIエージェント環境を検出すると、自動的に非対話モードを有効にする変更も追加されました。これにより、入力が必要なコマンドが見えないプロンプトで止まり続けるのではなく、早い段階で明確に処理されるようになります。(GitHub)

自動検出を無効にする場合は、次の環境変数を使用できます。

AZD_NON_INTERACTIVE=false

ただし、無人実行するCI/CDでは、対話モードを有効にすると再び入力待ちが発生する可能性があります。通常は自動検出を利用しつつ、スクリプトにも--no-promptを明示して、コマンドの意図を分かりやすくしておく運用が適しています。

fresh agentで修正を確認する方法

既存エージェントにはTerraformの初期化情報が残っている可能性があるため、修正確認は新しいエージェントで行うのが確実です。

確認項目期待する結果
azd version1.28.1以上
.terraformがない状態でazd down --no-promptを実行バックエンド初期化後、削除プランを表示
azd down --no-promptの終了ハングせず正常終了
Azureリソース削除されていない
検証用環境でazd down --no-prompt --forceを実行バックエンド初期化後、削除が進む
ジョブログ「backend initialization required」で停止しない

検証時は、本番環境ではなく、削除しても問題のないテスト環境を使用してください。

なお、azdがterraform initを呼び出すようになっても、次の問題まで自動的に解決されるわけではありません。

  • Azureへの認証が完了していない
  • リモートステートへのアクセス権がない
  • Storage Accountへのネットワーク接続が遮断されている
  • バックエンド設定ファイルが生成できない
  • 必要なTerraformプロバイダーを取得できない
  • サブスクリプションや環境変数が誤っている

修正後も初期化エラーが出る場合は、旧バージョンの不具合ではなく、認証、権限、ネットワーク、バックエンド設定を確認します。

更新後もハングまたは失敗する場合の確認ポイント

実際に使用されているazdが古くないか

ログにazd versionを出し、1.28.1以上であることを確認します。

更新コマンドが成功していても、別の場所にある旧バージョンがPATHで優先されている可能性があります。

削除目的なのに–forceが抜けていないか

修正版のazd down --no-promptは、削除プレビュー用です。

リソースを削除したいジョブで次のコマンドだけを実行しても、リソースは残ります。

azd down --no-prompt

削除が目的なら、次のようにします。

azd down --no-prompt --force

CIキャッシュやコンテナーイメージが更新されているか

CI設定を変更しても、古いツールキャッシュやコンテナーイメージが再利用されることがあります。

キャッシュキー、イメージタグ、エージェント再起動の必要性を確認してください。latestのような可変タグだけに依存せず、ジョブログに実バージョンを出すことが重要です。

Terraformバックエンドへアクセスできているか

terraform initが自動化されても、リモートバックエンドへのアクセス権限は必要です。

Azure Storageをバックエンドとして利用している場合は、CIの実行IDが対象ストレージへアクセスできるか、ファイアウォールやプライベートエンドポイントの制限に引っかかっていないかを確認します。

azd以外の処理が入力を待っていないか

azdのハングが解消したあともジョブが停止する場合は、プロジェクトフック、シェルスクリプト、Terraformの外部データソース、呼び出された別ツールが入力待ちになっていないかを調べます。

azd downの前後にログを出すと、停止位置を特定しやすくなります。

echo "Starting azd down"
azd down --no-prompt --force
echo "Completed azd down"

複数レイヤー構成では「何も変更されていない」とは限らない

PR #9143では、Terraformレイヤーがプレビューだけで終了した場合、azdが環境全体を削除したような成功メッセージを表示しないよう修正されています。(GitHub)

ただし、複数のInfrastructure as Codeレイヤーを持つプロジェクトでは、あるTerraformレイヤーが削除をスキップしても、別のレイヤーで処理が行われている可能性があります。

そのため、複数レイヤー構成では次の点を確認してください。

  • どのレイヤーがプレビューされたか
  • どのレイヤーで削除処理が行われたか
  • Azure上に残っているリソース
  • Terraformステートの状態
  • ジョブ全体ではなく、レイヤーごとのログ

azd down --no-promptが終了コード0になったことだけを根拠に、環境全体が削除済み、または一切変更されていないと判断しないことが重要です。

まとめ

CIでazd down --no-promptがハングする問題と、fresh agentでTerraformバックエンドの初期化に失敗する問題は、PR #9143を含むazd 1.28.1で修正されました。2026年7月ロールアップを基準にする場合は、1.29.0以上へ更新します。(GitHub)

更新後の使い分けは明確です。

  • 削除内容の確認:azd down --no-prompt
  • 実際の削除:azd down --no-prompt --force
  • fresh agent:azdがTerraformバックエンドを非対話モードで初期化
  • バージョン確認:azd version
  • CIでは終了コードだけで削除完了を判定しない

まずCIジョブの冒頭にazd versionを追加し、1.28.1未満であればazdを更新してください。そのうえで、プレビュー用ジョブと--forceを使う削除用ジョブを分離するのが、安全で再現性の高い修正方法です。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次