はじめに
インターンシップを素晴らしい企業体験にするためには、課題に対して必要なリソースを素早く学生に提供する必要がありますよね。
すぐにでも課題の開発を始めたいのに、渡したパソコンにVirtualBoxを入れて仮想マシンにOSをインストールしてもらって...なんてことをやってたら、ただでさえ限られた時間がどんどん減ってしまいます。
今回はProxmox VEとcloud-initを組み合わせて必要なリソースのVMを素早く提供する方法について、CLIとTerraformを使った2パターンをご紹介します。
Proxmox VE自体については https://pve.proxmox.com/wiki/Main_Page を参照ください。
用意するもの
- Proxmox VE 7.2がインストールされたマシン
以降は、Proxmox VEで仮想マシンが起動できる状態になったことを前提に進行します。
この記事では 7.2-14
以降をベースに記載しています。
仮想マシンのテンプレートの準備
まずは、ベースとなる仮想マシンイメージを作成しましょう。
今回は Ubuntu-22.04 のクラウドイメージを使用します。
クラウドイメージの取得
wget https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img -O ubuntu-22.04-server-cloudimg-amd64.img
ベースとなる仮想マシンの作成とテンプレート化
# Base VM configuration
qm create 9100 --net0 virtio,bridge=vmbr0
qm importdisk 9100 ubuntu-22.04-server-cloudimg-amd64.img local-lvm
qm set 9100 --name ubuntu-22.04a
qm set 9100 --scsihw virtio-scsi-pci --virtio0 local-lvm:vm-9100-disk-0
qm set 9100 --boot order=virtio0
qm set 9100 --ide2 local-lvm:cloudinit
qm set 9100 --nameserver 192.168.0.1 --searchdomain example.com
# Convert VM to VM Template
qm template 9100
ネットワーク設定は、管理者が把握しているという前提で、以下のように設定します。
- 接続先bridge: vmbr0
- subnet: 192.168.0.0/24
- gateway: 192.168.0.1
- nameserver: 192.168.0.1
- domain: example.com
ここまでで、ベースのVM TemplateがProxmox VE上に作成されました。
提供の作業フロー
それでは 4 vCPU/8GB Memory/120GB Disk の仮想マシンが要望されたと仮定して、それを提供してみましょう。
作業フローは以下の通りです。
- 利用者は以下の情報を管理者に知らせる
- 必要な仮想マシンのサイズ(今回は 4 vCPU/8GB Memory/120GB Disk)
- ログイン用のユーザー名(sample01)と公開鍵(sample01-rsakey.pub)
- 管理者は受け取った情報から仮想マシンを作る
- IPアドレスは管理者が把握しているという前提で
192.168.0.11
に設定します。
- IPアドレスは管理者が把握しているという前提で
- 管理者は仮想マシン作成後、利用者にアクセス先のIPアドレスを通知する
- 完了
仮想マシンの提供(CLIを使うケース)
作成したテンプレートをクローンして、構成を変更して起動します。
IPアドレスやログイン情報をcloud-initで設定できるところが非常に便利です。
qm clone 9100 1001 --name sample01 --full --storage local-lvm
qm set 1001 --cores 4
qm set 1001 --memory 8192
qm resize 1001 virtio0 120G
qm set 1001 --ipconfig0 ip=192.168.0.11/24,gw=192.168.0.1
qm set 1001 --ciuser sample01 --sshkeys sample01-rsakey.pub
qm start 1001
あとは、使用者にIPアドレスを伝えて完了です。
これで必要なリソースを持った仮想マシンを提供できました。
これなら、管理者は使用者のパスワードを知る必要も、ログイン後に初期パスワードの変更を依頼する必要もありませんね。
仮想マシンの提供(Terraformを使うケース)
Proxmox VEではTerraformを使うこともできます。
早速 Proxmox Provider を使ってCLIと同じようなことができるか試してみましょう。
今回は管理者が実行するので、かなり緩めの設定をしていきます。
細かくリソースプールや権限を設定して、管理者以外のユーザーが直接Terraformを使えるようにしても良いでしょう。
APIトークンの取得
root権限をそのまま継承( --privsep 0
)したAPIトークンを作成します。
# pvesh create /access/users/root@pam/token/qiita-sample --privsep 0
┌──────────────┬──────────────────────────────────────┐
│ key │ value │
╞══════════════╪══════════════════════════════════════╡
│ full-tokenid │ root@pam!qiita-sample │
├──────────────┼──────────────────────────────────────┤
│ info │ {"privsep":"0"} │
├──────────────┼──────────────────────────────────────┤
│ value │ d2f33ee3-bf19-4155-bd7c-e23a3f14522d │
└──────────────┴──────────────────────────────────────┘
このトークンを使用することで、root権限で好きなだけProxmox VEのAPIを実行できます。
Terraformの記述
使用したTerraformのバージョンです。
$ terraform -version
Terraform v1.3.9
on linux_amd64
+ provider registry.terraform.io/telmate/proxmox v2.9.11
Terraformの記述例です。
variable username {}
variable public_key {}
variable cores {}
variable memory {}
variable disk_size {}
variable ip_address {}
terraform {
required_providers {
proxmox = {
source = "telmate/proxmox"
version = "2.9.11"
}
}
}
provider "proxmox" {
pm_api_token_id = "root@pam!qiita-sample"
pm_api_token_secret = "d2f33ee3-bf19-4155-bd7c-e23a3f14522d"
pm_api_url = "https://pve-sample:8006/api2/json"
pm_tls_insecure = true
}
resource "proxmox_vm_qemu" "intern-vm" {
name = "intern-vm-${var.username}"
target_node = "pve-c01"
clone = "ubuntu-22.04a"
os_type = "cloud-init"
boot = "order=virtio0"
cores = "${var.cores}"
memory = "${var.memory}"
disk {
storage = "local-lvm"
type = "virtio"
size = "${var.disk_size}G"
}
network {
model = "virtio"
bridge = "vmbr0"
firewall = false
}
ipconfig0 = "ip=${var.ip_address}/24,gw=192.168.0.1"
ciuser = "${var.username}"
sshkeys = <<EOF
${var.public_key}
EOF
}
なお最新のTerraform providerは 2.9.13
ですが、API Token周りにバグがある terraform-provider-proxmox/issues/703 ようなので 2.9.11
を使用しています。
作成したいVMの情報を記載した変数ファイルを作成します。
$ cat sample01.tfvars
username = "sample01"
public_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHZYaK+tKWpOVCxhKeTeoKLW/UoAOaj03QXPGrqY2JQm user@sample"
cores = 4
memory = 8192
disk_size = 120
ip_address = "192.168.0.11"
Terraformの実行例
実行例です。
$ terraform apply -var-file sample01.tfvars
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# proxmox_vm_qemu.intern-vm will be created
+ resource "proxmox_vm_qemu" "intern-vm" {
+ additional_wait = 0
+ agent = 0
+ automatic_reboot = true
+ balloon = 0
+ bios = "seabios"
+ boot = "order=virtio0"
+ bootdisk = (known after apply)
+ ciuser = "sample01"
+ clone = "ubuntu-22.04a"
+ clone_wait = 0
+ cores = 4
+ cpu = "host"
+ default_ipv4_address = (known after apply)
+ define_connection_info = true
+ force_create = false
+ full_clone = true
+ guest_agent_ready_timeout = 100
+ hotplug = "network,disk,usb"
+ id = (known after apply)
+ ipconfig0 = "ip=192.168.0.11/24,gw=192.168.0.1"
+ kvm = true
+ memory = 8192
+ name = "intern-vm-sample01"
+ nameserver = (known after apply)
+ numa = false
+ onboot = false
+ oncreate = true
+ os_type = "cloud-init"
+ preprovision = true
+ reboot_required = (known after apply)
+ scsihw = (known after apply)
+ searchdomain = (known after apply)
+ sockets = 1
+ ssh_host = (known after apply)
+ ssh_port = (known after apply)
+ sshkeys = <<-EOT
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHZYaK+tKWpOVCxhKeTeoKLW/UoAOaj03QXPGrqY2JQm user@sample
EOT
+ tablet = true
+ target_node = "pve-c01"
+ unused_disk = (known after apply)
+ vcpus = 0
+ vlan = -1
+ vmid = (known after apply)
+ disk {
+ backup = 0
+ cache = "none"
+ file = (known after apply)
+ format = (known after apply)
+ iops = 0
+ iops_max = 0
+ iops_max_length = 0
+ iops_rd = 0
+ iops_rd_max = 0
+ iops_rd_max_length = 0
+ iops_wr = 0
+ iops_wr_max = 0
+ iops_wr_max_length = 0
+ iothread = 0
+ mbps = 0
+ mbps_rd = 0
+ mbps_rd_max = 0
+ mbps_wr = 0
+ mbps_wr_max = 0
+ media = (known after apply)
+ replicate = 0
+ size = "120G"
+ slot = (known after apply)
+ ssd = 0
+ storage = "local-lvm"
+ storage_type = (known after apply)
+ type = "virtio"
+ volume = (known after apply)
}
+ network {
+ bridge = "vmbr0"
+ firewall = false
+ link_down = false
+ macaddr = (known after apply)
+ model = "virtio"
+ queues = (known after apply)
+ rate = (known after apply)
+ tag = -1
}
}
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
proxmox_vm_qemu.intern-vm: Creating...
proxmox_vm_qemu.intern-vm: Still creating... [10s elapsed]
proxmox_vm_qemu.intern-vm: Still creating... [20s elapsed]
proxmox_vm_qemu.intern-vm: Still creating... [30s elapsed]
proxmox_vm_qemu.intern-vm: Still creating... [40s elapsed]
proxmox_vm_qemu.intern-vm: Still creating... [50s elapsed]
proxmox_vm_qemu.intern-vm: Still creating... [1m0s elapsed]
proxmox_vm_qemu.intern-vm: Creation complete after 1m6s [id=pve-c01/qemu/103]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
もちろん、削除も terraform destroy -var-file sample01.tfvars
で簡単です。
おしまい
今回はProxmox VEとcloud-initにTerraformを組み合わせてVMを作る方法を書いてみました。
大抵のことはパブリッククラウドサービスで何とかなるとはいえ、手元の機材を使いたいケースもありますので、上手く使ってみてください。