💭

Terraform + ProxmoxでVMが起動しないときの備忘録

2024/12/30に公開

Terraform + Proxmox + Cloud-init でVMが起動しないときの備忘録

1. はじめに

この記事ではProxmox VE環境でTerraformを用いて仮想マシン(VM)を構築する際に直面した、少し厄介な問題について、あまり参考資料が見つからなかったため備忘録がてら解説を残しておきます。
もしかしたら一般的な常識で私が知らないだけかもしれません。

具体的な問題としてはTerraformでVMを定義し、terraform applyによってプロビジョニングした関わらず、VMが正常に起動しないという状況に陥りました。

2. 問題:Terraform で作成した Proxmox VM が起動しない

発生した問題の詳細

Proxmox環境でTerraformを使ってVM構築を自動化しようとした際、ある問題に直面しました。Terraformのコードを記述し、terraform applyを実行すると、Proxmox上にVMは確かに作成されるのですが、なぜかVMが起動しないのです。

当時の具体的な設定と状況は以下の通りです。また途中でアップデートを試みたため、最終的な動作確認ができたバージョンを記載しています。

  • 使用環境:
    • 仮想化基盤: Proxmox VE (Virtual Environment 8.2.4)
    • インフラ構築ツール: Terraform (Version 1.0以降を想定)
      • telmate/proxmox: 3.0.1-rc4
    • VM初期設定ツール: Cloud-init
  • 設定内容:
    1. Cloud-init OSイメージの準備:
      Proxmox上で、Cloud-initの設定ファイル(例えば、初期ユーザー設定、SSH公開鍵、ネットワーク設定など)を記述したVMイメージ(例:cloudinit.img)を作成済み。このイメージはテンプレート化を経て、VM起動時にCloud-initによって読み込まれます。※末尾の参考資料を参考にしてください。
    2. Terraform設定ファイルの記述:
      Terraformの設定ファイル内で、proxmox_vm_qemuリソースを定義し、os_type"cloud-init" を指定、さらに clone には、手順1で作成したテンプレートの名前(例:amd64-template)を設定。
      resource "proxmox_vm_qemu" "example" {
        name = "my-vm"
        target_node = "proxmox-node"
        os_type = "cloud-init"
        clone = "amd64-template" # Cloud-initのテンプレート名を指定
        cores = 2
        memory = 2048
        
        ...
        disk {
          storage = "local-btrfs"
          type = "scsi"
          size = "32G"
        }
        ...
      }
      
    3. Terraform applyの実行:
      Proxmoxとは異なるマシンから、terraform applyを実行。
  • 発生した問題:
    • Terraformは正常に終了し、VMがProxmox上に作成される。
    • しかし、VMを起動しようとすると、起動プロセスが進まない。
    • VMは停止状態固定で動作不可(当然shellなども使えない)

問題の原因調査

  1. 【失敗】まず、terraform providerのバージョンが古いことを懸念し、バージョンアップを行いました。これは2.x.x系を使っていて、3.x.x系に移行するときに記載方法に破壊的変更があったようにchangelogから読み取れたためです。
    ただこれは結果的あまり効果はありませんでした。(アップデートできたおまけ付きでしたが)

  2. 【失敗】proxmoxの初期化・再インストール
    これはVMが作成できているので、terraform側の問題ではなくマシンの問題ではないかと疑ったためです。
    こちらも効果なしでした。

  3. 【失敗】もう少し問題を切り分けるために、ProxmoxのWeb UIから問題のVMを手動で起動を試みるとVMが起動しました。しかし、動作がおかしく通常通りには使えませんでした。
    (ただ起動できただけでも進展!)

  4. 【成功】1.~3.からどうやらterrafromからの作成とproxmox上での手動作成に差分がありそうです。
    そこでProxmoxの仮想マシンの詳細設定を詳しく確認したところ、手動起動時にはCloud-initのイメージが、通常のディスクとしてマウントされていることに気づきました。
    terrafromからの作成時には名前は表示されますが、マウントはされていませんでした。
    Terraformの設定ファイルで、os_type = "cloud-init" と指定しても、Proxmoxは単にそのイメージを認識しているだけで、データファイル(ディスク)として解釈してくれないようです。

Proxmoxでは、Cloud-initのイメージをVM起動時に読み込ませるためには、特定のディスクコントローラに対して、ディスクマウントの設定を行う必要があります。Terraformの設定だけでは、この情報がProxmoxに伝わらず、結果としてVMからみると読み込み元のディスクがないため、起動に失敗していたのです。

3. 解決策:ide2 を設定に追加する

問題の本質

前述の通り、Cloud-initのVMイメージファイルはProxmoxから見ると単なるディスクとして認識されてしまうため、Proxmoxに対して、どのディスクコントローラにCloud-initの設定を適用するか明示的に指定する必要がありました。

解決策の詳細

この問題を解決するために、Terraformの設定に ide ブロックを追加し、その中に ide2 ブロックを定義し、cloudinit の設定を記述しました。これにより、Proxmoxは、ide2 コントローラに接続されたディスクを、Cloud-initの初期設定ファイルとして認識するようになります。

※ここではide2にしていますが、テンプレートの作成次第で変わるはず...適当に補完してください。

resource "proxmox_vm_qemu" "example" {
  ...
  disks {
    scsi {
      ...
      # ここに通常使うディスクはマウントするはず
      ...
    }
    ide {
      ide2 {
        cloudinit {
          storage = "local-btrfs"
        }
      }
    }
  }
  ...
}

この設定により、Proxmoxはide2に接続されたディスクをCloud-init用の設定ファイルとして認識し、VMの起動時にCloud-initの初期設定が実行されるようになります。storageパラメータは、Cloud-initのISOイメージが保存されているProxmoxのストレージを指定します。この例では、local-btrfsというストレージを指定しています。

Reference

Discussion