[Proxmox VE] Cloud-initで新しいインスタンスの作成を簡単にする

:::note warn
この記事が筆者の初投稿の記事なので、読みにくい点があるかもしれません。ご容赦ください。
:::

## この記事で紹介すること

Proxmox VEでCloud-initを用いて初期設定をできるようにします。
Cloud-initで初期設定可能な仮想マシンを作成し、それをテンプレート化、テンプレート化したVMを複製して、簡単に初期設定できるようにします。

筆者は数か月前にProxmoxをインストールして、いろいろ遊ぶために仮想環境を作っては壊してを繰り返しています。新しい仮想マシンを作成するときに、普通にインストールしたDebianの仮想マシンを、クローンして新しい仮想マシンを作成していました。
ですが仮想マシンを立ち上げるときに、**IPアドレス・ホスト名を書き換えるのがめんどくさい**と思い、初期化時にユーザー名、パスワード、IPアドレスなどを、管理画面から設定できるCloud-initを使ってみることにしました。

すでに同様のことをされている記事はたくさんありますが、備忘録兼ねて記事にします。
最終的なコードが欲しい方は、ページ末尾の[こちら](#最終的なコード)で確認して下さい。

### Cloud-init とは
Cloud-initは、ゲストマシンの初期化中に、ホストマシンで事前に設定した設定項目を自動で適応してくれるアプリケーションらしいです。
面倒なインストール手順を踏まなくても、管理画面でユーザ名とかパスワードとかを入れると、勝手に設定を適応してくれます。
Proxmoxは、ユーザ名、パスワード、SSHの公開鍵、DNSドメイン・サーバ、IP構成を設定できます。

## 環境
- ホスト: Proxmox VE 8.2.2
- ゲスト: Debian 12

## やってみる。

### Debianのクラウドイメージをダウンロード

Debianの[公式ダウンロードページ]()から、Debianのクラウドイメージをダウンロードします。クラウドイメージとは通常のインストールイメージとは違い、仮想環境で実行するのに最適化されているイメージです。  

https://cloud.debian.org/images/cloud/

上のページにアクセスし、下にスクロールして**`BookWarm/`**(Debian 12のコードネーム）から、それぞれの環境にあったイメージを見つけてください。拡張子は`.qcow2`のものを選んでください。

筆者は`debian-12-generic-amd64.qcow2`を選びました。
`debian-12-generic-(アーキテクチャ)-latest.qcow2`のものを選んでいれば間違いないと思います。
リンクをコピーし、`wget (リンク)`をホストのコンソールで実行して、イメージをダウンロードします。

```bash
$ wget https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2
```

### VMのテンプレートを作成

VM IDは`9000`、テンプレートとなるVMの名称は`debian12-cloudinit`として、テンプレートを作成します。

#### VMを作成
VMを作成します。
- `qm create 9000`
    - VMIDを `9000` にしてVMを新規作成
- `--name debian12-cloudinit`
    - VMの名前を `debian12-cloudinit` にする
- `--net0 virtio,bridge=vmbr0`

```bash
$ sudo qm create 9000 --name debian12-cloudinit --net0 virtio,bridge=vmbr0
```

#### VMにクラウドイメージをインポート
ダウンロードしてきたクラウドイメージをインポートする
```bash
$ sudo qm importdisk 9000 ./debian-12-generic-amd64.qcow2 local-zfs
```

#### SCSIコントローラ・ハードディスクを設定
- `--scsihw virtio-scsi-pci` 
    - ハードディスクなどを管理するSCSIコントローラを設定します
- `--scsi0 local-zfs:vm-9000-disk-0,discard=on`
    - ハードディスクとして、先ほど設定したクラウドイメージが入っているボリュームを選択します
    - `discard=on` によってストレージを節約することができるらしいです

```
$ sudo qm set 9000 --scsihw virtio-scsi-pci --scsi0 local-zfs:vm-9000-disk-0,discard=on
```

#### Cloud-Initデバイスをセットする

```
$ sudo qm set 9000 --ide2 local-zfs:cloudinit
```

#### QEMUを有効化する
Qemu-guest-agentを有効化します。
QEMUを使うためには、ホスト側・ゲスト側双方の設定が必要です。
ゲスト側での設定は後ほど行います。
```
$ sudo qm set 9000 --agent enabled=1
```

#### OSの種別を指定する
OSの種別をLinuxに指定します。
OSの種別の指定をしなくてもそこまで影響はないという情報を見つけましたが、詳しくはわかりませんでした。有識者の方教えてください！
```
$ sudo qm set 9000 --ostype l26
```

#### ディスクをリサイズ
ハードディスク(scsi0)の容量を16GBに拡張・リサイズします。
あとでクローンするときに時間がかかるので、実際に使用する容量よりも少なめに設定しています。
```bash
$ sudo qm resize 9000 scsi0 16G
```

#### メモリサイズを指定
筆者はメモリを2GBに指定しました。
```bash
$ sudo qm set 9000 --memory 2048
```

#### テンプレート化
最後にテンプレート化します。
```
$ sudo qm template 9000
```

### テンプレート化したVMをクローン
ProxmoxのWeb GUIから、テンプレート化したVMをクローンします。
VMID、VMの名称は任意で、Cloud-initのタブからユーザ名、パスワードなどを設定したのちに、仮想マシンを起動してください。

### VMにQEMUをインストールする
さきほど設定したユーザ名とパスワードでログインし、QEMUをインストールします。
```
$ sudo apt install qemu-guest-agent
$ sudo systemctl start qemu-guest-agent
$ sudo systemctl enable qemu-guest-agent
```
これで管理画面からIPアドレスを確認できるようになりました！

## 最終的なコード

適宜読み替えてください。
- VMのID `9000`
- テンプレートのVM名 `debian12-cloudinit`
- ホストのディスク名 `local-zfs`

```shell
# ホストで実行
$ sudo qm create 9000 --name debian12-cloudinit --net0 virtio,bridge=vmbr0
$ sudo qm importdisk 9000 ./debian-12-generic-amd64.qcow2 local-zfs
$ sudo qm set 9000 --scsihw virtio-scsi-pci --scsi0 local-zfs:vm-9000-disk-0,discard=on
$ sudo qm set 9000 --ide2 local-zfs:cloudinit
$ sudo qm set 9000 --serial0 socket --vga serial0
$ sudo qm set 9000 --ostype l26
$ sudo qm set 9000 --memory 2048
$ sudo qm set 9000 --boot c --bootdisk scsi0
$ sudo qm resize 9000 scsi0 16G
$ sudo qm set 9000 --agent enabled=1
$ sudo qm template 9000

# テンプレート化したVMをクローン・Cloudinitの設定をした後、ゲストのコンソールで以下のコマンドを実行
$ sudo apt install qemu-guest-agent
$ sudo systemctl start qemu-guest-agent
$ sudo systemctl enable qemu-guest-agent
```

## さいごに
自分でクラウドイメージを作成すれば、Cloud-initで設定できる項目がもっと増えるみたいなのですが、少し手順が多いので今回はしませんでした。詳しくはProxmoxのドキュメントを参照してください。

https://pve.proxmox.com/wiki/Cloud-Init_FAQ#Creating_a_custom_cloud_image

## 追記・`su`コマンドでrootになれない

rootユーザのパスワードが設定されていないのが原因みたいです。
`su`コマンドより、コマンドの前に`sudo`をつけて実行するほうが安全だからだそう。

https://superuser.com/questions/1224340/debian-9-su-command-not-working