bpg/proxmox providerで proxmox_virtual_environment_file(snippets)を作ろうとしたらSSH認証エラーになった。調べてみたところ、providerがファイルアップロードだけSSH/SFTP経由で行うためだった。ってことで、APIトークンとは別にSSH接続の設定が必要だということがわかったという記録です。
エラー内容
bpg/proxmox providerでcloud-init用のsnippetsをアップロードしようとしたら、こういうエラーが出たんですよ。
Error: failed to open SSH client: unable to authenticate user "" over SSH to "192.168.11.50:22". Please verify that ssh-agent is correctly loaded with an authorized key via 'ssh-add -L' (NOTE: configurations in ~/.ssh/config are not considered by the provider): failed to dial 192.168.11.50:22: ssh: handshake failed: ssh: unable to authenticate, attempted methods [none password], no supported methods remain
APIトークンはちゃんと設定してあって、VM作成とか起動停止は普通に動いてたんですよね。なのにsnippetsのアップロードだけSSH?ってなりました。
原因
bpg/proxmox providerは、操作の種類によって通信経路を使い分けてます。
Terraform (bpg/proxmox provider)
│
├─ VM作成・設定変更・起動停止
│ └─→ Proxmox REST API (port 8006)
│ 認証: APIトークン
│
└─ ファイルアップロード (snippets等、APIが非対応なファイル)
└─→ SSH/SFTP (port 22)
認証: SSH鍵 + ssh-agent
| 操作 | 経路 | 認証 | ポート |
|---|---|---|---|
| VM作成、設定変更、起動停止 | Proxmox REST API | APIトークン | 8006 |
| snippets等のアップロード | SSH/SFTP | SSH鍵 | 22 |
Proxmox APIのアップロードエンドポイント(/nodes/{node}/storage/{storage}/upload)はISOやvztmplなど一部のファイルタイプしか対応していなくて、snippetsのような任意テキストファイルは対象外なんですよね。だからproviderがSSH/SFTPでProxmoxホストに直接ファイルを置きに行く設計になってます。
providerのバグじゃなくて、Proxmox API側の制約をSSHで補っている形。GitHub上でも「SSHなしでsnippetsをアップロードしたい」というIssue(#2112)が立ってます。
解決方法
3ステップです。
1. Proxmoxホストに鍵認証でSSH接続できるようにする
ssh-copy-id root@<proxmox-host>
接続確認:
ssh root@<proxmox-host> hostname # → pve(Proxmoxのホスト名が返ればOK)
2. providerにsshブロックを追加する
provider "proxmox" { endpoint = var.proxmox_endpoint api_token = var.proxmox_api_token insecure = true ssh { agent = true username = "root" } }
username = "root" がないとSSHユーザー名が空のままになって、冒頭の unable to authenticate user "" が出ます。
3. ssh-agentを起動して鍵をロードする
eval "$(ssh-agent -s)" ssh-add ~/.ssh/id_ed25519
確認:
ssh-add -l # → 256 SHA256:xxxxx ... (ED25519) のように鍵が表示されればOK # (エラーメッセージ中の -L は公開鍵全文の出力、-l はフィンガープリント一覧。確認用途はどちらでもOK)
ここまでやって terraform apply でSSHエラーが消えれば設定完了。terraform plan ではSSH接続を試さない場合があるので、最終確認は apply で行ってください。
eval "$(ssh-agent -s)" はシェルセッション限りなので、ターミナルを閉じると無効になります。CI/CDやsystemd timerから実行する場合は、providerの private_key オプションで鍵ファイルを直接指定する方法を検討してください。
ssh { username = "root" private_key = file(pathexpand("~/.ssh/id_ed25519")) # ssh-agentが使えないCI環境向け。agent = true は不要 }
秘密鍵ファイルの配置場所とパーミッションには注意してください。
なぜ気づきにくいか
このハマりが厄介なのは、段階的に表面化するところです。
- VM作成まではAPIトークンだけで正常に動く → 「認証設定は完了した」と思い込む
- cloud-initのsnippetsを追加した途端にSSHエラーが出る → 「何も変えてないのに壊れた」感覚
- エラーメッセージにSSHと書いてあるけど、Terraform providerの文脈でSSHが出てくると思ってない
providerのドキュメントにSSH設定の必要性は書いてあるんですけど、「VM作成」のチュートリアルだけ読んで進めるとSSH設定を飛ばしがち。
あと、~/.ssh/config の設定はproviderに無視されるので注意。エラーメッセージにも configurations in ~/.ssh/config are not considered by the provider って書いてあります。
セットアップチェックリスト
bpg/proxmox providerでsnippetsを使う場合、最初に確認しておくべきことをまとめておきます。
□ APIトークン設定済み(provider.endpoint + api_token) □ SSH鍵認証設定済み(ssh-copy-id + provider.ssh ブロック) □ ssh-agentが起動している(ssh-add -l で確認) □ Proxmoxストレージで Snippets コンテンツタイプが有効
4番目の「Snippetsコンテンツタイプの有効化」も忘れがちです。SSH設定が完了してもストレージ側でsnippetsが無効だと別のエラーになります。有効化はProxmox UIから「データセンター → ストレージ → local → 編集」でSnippetsにチェックを入れるのが安全です。CLIで pvesm set local --content ... を使う場合は既存の設定を上書きするので、先に pvesm config local で現在のcontent設定を確認してからにしてください。
まとめ
bpg/proxmox providerでsnippetsがSSHエラーになるのは、Proxmox APIがsnippetsのアップロードに対応していなくて、providerがSSH/SFTPで代替しているから。APIトークンとSSH鍵認証は別の認証経路なので、両方を設定する必要があります。