最近、個人的に Azure Developer CLI (azd) という超便利ツールが熱い。
azd up
コマンドでインフラ含めて Azure Functions とかの実行環境をサクッと作れて、書いたコードをすぐに動かせる。
コードもテンプレートがあるのでゼロから書く必要がない。
たぶん azd だけでは自分に刺さらなかった。 Functions で Flex Consumption が使えるようになったり、生成 AI のおかげで自分でもそれっぽいコードを書けたり、色々条件が重なったからこそ今 azd の便利さの片鱗を味わえている。
そんな azd はアプリケーション実行環境の土台となる Azure リソースを Bicep を使ってプロビジョニングする。 そして、まだベータ版だが Terraform も使える。
Terraform を使うということはステート管理の話が出てくる。 当然 azd もステート管理を考慮していて、デフォルトのローカルステート(ローカル環境にステートファイルをそのまま置くやつ)に加えて、リモートステートとして Azure Storage にステートファイルを格納できる。
普段 HCP Terraform を使っている身としては「azd のステートファイルを HCP Terraform に格納できるのか」というのが気になるところ。
結論から言うと今はまだ azd で HCP Terraform にステートファイルを格納できなかった。 今回はそのことについて書く。
確認に使った各ツールのバージョンは次の通り。
- azd
v1.13.0
- terraform
v1.11.0
要約
azd で HCP Terraform を使えない理由は以下のとおり。
- HCP Terraform は「VCS-driven」と「CLI-driven」という連携方法がある(「API-driven」は割愛)
- Plan ファイルを保存する azd では「VCS-driven」は使えない
- ステートロックが無効化されている azd では「CLI-driven」は使えない
そもそも azd で Terraform を使うためにはいくつか設定が必要になるが、詳しくは Microsoft の公式ドキュメントを見てもらいたい。

Terraform を Azure Developer CLI (azd) のコードとしてのインフラストラクチャ ツールとして使用する
azd のステート管理
冒頭でも述べたように、azd で Terraform を使う場合はステート管理として「ローカルステート」か「リモートステート」を選ぶことになる。 これは通常の Terraform の使い方と同じ。
デフォルトは「ローカルステート」で、ステートファイルは .azure/<env-name>/infra/terraform.tfstate
に作られる。
Terraform のように terraform init
しなくても azd up
(アプリとインフラ作成) や azd provision
(インフラだけ作成) の中でよしなに Init してくれる。
-upgrade
オプションもついてくる。
ローカルステートだと要件的に不十分なことがあるので「リモートステート」を選ぶこともある。 Microsoft のドキュメントではリモートステートを選ぶシナリオとして次のようなものが挙げられている。
- 状態データへの共有アクセスを許可し、そのインフラストラクチャ リソースのコレクションで複数のユーザーが共同作業できるようにする
- 状態ファイルに含まれる機密情報が公開されないようにする
- 状態をローカルに格納しているために誤って削除される可能性を減らす
azd でステートファイルを共有することがあるのか?という疑問もありつつ、誤ってステートファイルを削除してしまうことはあるかもしれない。 機密情報が公開されないようにするのはもっともだ。
ということでリモートステートを使う場合だが、ステートファイルの格納先は Azure Storage を使うことになる。 これは現在の azd の仕様。
Azure Storage をリモートステートとして使うために以下をおこなう。
- .tf ファイルの terraform ブロックに
backend "azurerm"
を設定 infra/provider.config.json
ファイルを追加- 環境変数を設定
詳しくは Microsoft のドキュメント「リモート状態を有効にする」を見てもらいたい。 これらの設定を正しく終えると、azd で作ったリソースのステート管理が Azure Storage に移る。
このように、azd では「ローカルステート」と「リモートステート」を選択できるようになっている。 ということでリモートステートとして HCP Terraform が使えるか試してみた。
Plan ファイルを保存する azd では「VCS-driven」は使えない
まずは「VCS-driven」を試す。
「VCS-driven」は Terraform 構成を管理する Git リポジトリと紐づき、Terraform 構成が更新されると自動的に Plan や Apply を実行できる。
HCP Terraform に「VCS-driven」を設定したワークスペースを用意しておき、terraform ブロックの backend "azurerm"
の代わりに cloud
を追加する。
terraform {
cloud {
organization = "<ORGANIZATION-NAME>"
workspaces {
name = "<WORKSPACE-NAME>"
}
}
}
この状態で azd provision
してみると次のエラーが出た。
╷
│ Error: Saved plans not allowed for workspaces with a VCS connection
│
│ A workspace that is connected to a VCS requires the VCS-driven workflow to ensure that the VCS remains the single source of truth.
╵
--debug
オプションをつけて再実行してみると azd でどんな Terraform のコマンドが実行されたか分かる。
このコマンドを見ると azd では -out
オプションで Plan ファイルを出力していた。
terraform \
-chdir=<azd-dirctory>/infra \
plan \
-out=<azd-dirctory>/.azure/<env-name>/infra/main.tfplan \
-lock=false \
-var-file=<azd-dirctory>/.azure/<env-name>/infra/main.tfvars.json \
-state=<redacted>
エラーメッセージにも書いてあるとおり、“Single source of truth” の考えに則り「VCS-driven」では -out
による Plan ファイルの出力や、ワークスペース外の Plan ファイルで Apply ができないようになっている。
現時点では azd で -out
オプションを無効化するパラメータはないため、HCP Terraform の「VCS-driven」のワークスペースで azd のステートを管理できない。
ステートロックが無効化されている azd では「CLI-driven」は使えない
もう一つの「CLI-driven」はどうか。
「CLI-driven」はステートファイルの管理のみを HCP Terraform のワークスペースに任せてローカルで Plan や Apply できる機能で、リポジトリのコードが基準となる「VCS-driven」とは用途が異なる。 azd には「CLI-driven」のほうが適していると思う。
「CLI-driven」は HCP Terraform のワークスペース設定から変更できる。
変更後、同じように azd provision
してみるとリソースは作成されたが先ほどとは違うエラーになった。
╷
│ Error: Failed to save state
│
│ Error saving state: error uploading state: 409 Conflict
╵
╷
│ Error: Failed to persist state to backend
│
│ The error shown above has prevented Terraform from writing the updated state to the configured backend. To allow for recovery, the state has been written to the file "errored.tfstate" in the current working directory.
│
│ Running "terraform apply" again at this point will create a forked state, making it harder to recover.
│
│ To retry writing this state, use the following command:
│ terraform state push errored.tfstate
│
╵
HCP Terraform にステートを保存するときに競合が起きたらしい。
同じように --debug
オプションをつけてどんなコマンドが実行されたか確認すると、今度は Apply でエラーになっている。
terraform
\ -chdir=<azd-dirctory>/infra \
apply \
-lock=false \
-state=<redacted> \
<azd-dirctory>/.azure/<env-name>/infra/main.tfplan
azd では Apply 実行時にステートファイルのロックが無効化される -lock=false
オプションが設定されているため、どうやらロックを掛けないと HCP Terraform 側でエラーを返すようだ。
そして -lock=false
はハードコーディングされているため、現時点ではロックを掛けることができない。
Issue も上がっているので今後の動きに注目したい。

Feature request: Support Terraform state locking · Issue #4882 · Azure/azure-dev
ということで、HCP Terraform の「CLI-driven」も azd のステート管理として利用できない。
まとめ
個人的に熱い Azure Developer CLI (azd) で HCP Terraform と連携できないか試してみたが、現時点では連携できないことが分かった。
- azd で Terraform を使える(まだベータ版)
- HCP Terraform では「VCS-driven」と「CLI-driven」がある
- Plan ファイルを保存する & ステートロックが無効化されている azd では HCP Terraform でステート管理ができない
azd で Terraform を使うのはまだベータ版なので対応していない機能があって当然。 azd を HCP Terraform と連携させることはニッチな使い方だと思うが、連携できるようになると嬉しい。