Proxmoxに入門したのでTerraformにも入門してみた
概要
最近Proxmoxに入門したので、ついでにTerraformにも入門してみました。
どちらも初めて触るのでTerraformからVMを作れるようになるまで時間がかかりましたが、一応できたので備忘として残します。
なお、ProxmoxもTerraformも初心者なので間違っていることやもっといいやり方があると思いますがその辺はご容赦を...
前提
- Proxmox VEバージョン: 8.3.0
- Terraformバージョン: v1.12.2
- プロバイダ: Telmate/proxmox:3.0.2-rc01
TerraformからVMを作るまでの手順
VMのテンプレを作成
まずはVMのテンプレを作成します。
コマンドで作成するのでProxmoxにSSHで接続して直接コマンドを打ってください。
変数のところはそれぞれの環境に合わせて変更してください。
#### 変数 ####
VM_TEMPLATE_ID=9999
VM_TEMPLATE_NAME="ubuntu-2404-tmpl"
VM_TEMPLATE_MEMORY=2048
VM_TEMPLATE_CPU=2
VM_DISK_STORAGE="local-lvm"
UBUNTU_IMG_URL="https://cloud-images.ubuntu.com/releases/24.04/release/ubuntu-24.04-server-cloudimg-amd64.img"
UBUNTU_IMG_FILENAME=$(basename $UBUNTU_IMG_URL)
IMG_ISO_PATH="/var/lib/vz/template/iso"
SCRIPT_TMP_PATH="/tmp"
#### 変数 ####
# Ubuntuのimgファイルをダウンロードしてコピー
wget $UBUNTU_IMG_URL -O "$SCRIPT_TMP_PATH/$UBUNTU_IMG_FILENAME"
cp "/$SCRIPT_TMP_PATH/$UBUNTU_IMG_FILENAME" "$IMG_ISO_PATH/$UBUNTU_IMG_FILENAME"
# VMテンプレートの作成
qm create $VM_TEMPLATE_ID --name $VM_TEMPLATE_NAME --memory $VM_TEMPLATE_MEMORY --cores $VM_TEMPLATE_CPU --net0 virtio,bridge=vmbr0
qm set $VM_TEMPLATE_ID --scsihw virtio-scsi-single
qm set $VM_TEMPLATE_ID --virtio0 $VM_DISK_STORAGE:0,import-from="$SCRIPT_TMP_PATH/$UBUNTU_IMG_FILENAME"
qm set $VM_TEMPLATE_ID --boot c --bootdisk virtio0
qm set $VM_TEMPLATE_ID --ide2 $VM_DISK_STORAGE:cloudinit
qm set $VM_TEMPLATE_ID --serial0 socket --vga serial0
qm set $VM_TEMPLATE_ID --agent enabled=1,fstrim_cloned_disks=1
qm template $VM_TEMPLATE_ID
APIトークンの作成
ProxmoxのAPIトークンを作成します。具体的な手順はドキュメントなどを参照していただけると。
ログイン後に「データセンター > アクセス権限 > APIトークン」の「追加」から作成できる。
Terraform関連のファイルを作成
Terraformのファイルを作成します。同じディレクトリに全てのファイルを作成しています。
providers.tfの作成
Proxmoxを扱えるようにTerraform Registryにあるtemate/proxmox
を使用しました。
terraform {
required_version = ">=1.3.3"
required_providers {
proxmox = {
source = "telmate/proxmox"
version = "3.0.2-rc01"
}
null = {
source = "hashicorp/null"
version = "3.2.2"
}
}
}
provider "proxmox" {
pm_api_url = var.pm_api_url
pm_api_token_id = var.pm_api_token_id
pm_api_token_secret = var.pm_api_token_secret
pm_tls_insecure = var.pm_tls_insecure
pm_parallel = var.pm_parallel
pm_timeout = var.pm_timeout
}
variables.tfの作成
変数を定義します。ProxmoxのAPI関連とVMの設定値を定義しています。
### Proxmox VE ###
variable "pm_api_url" {
type = string
description = "ProxmoxのAPIエンドポイント"
}
variable "pm_api_token_id" {
type = string
description = "ProxmoxのAPIトークンID"
}
variable "pm_api_token_secret" {
type = string
description = "ProxmoxのAPIトークンシークレット"
sensitive = true
}
variable "pm_tls_insecure" {
type = bool
description = "TLS検証を無効にする"
}
variable "pm_target_node" {
type = string
description = "リソースを作成するProxmoxのノード"
}
variable "pm_parallel" {
type = number
description = "Proxmoxリソースの同時作成可能数"
default = 2
}
variable "pm_timeout" {
type = number
description = "Proxmox APIの呼び出しタイムアウト(秒)"
default = 600
}
### VMs ###
variable "vms" {
description = "作成するVMリスト"
type = list(object({
vmid = optional(number) # VMのID
name = string # VM名
tags = optional(string, "terraform") # VMに付与するタグ(default: terraform)
description = string # VMの説明
ubuntu_tmpl_name = string # VMのコピー元テンプレート
cpu_cores = number # VMのCPUコア数
cpu_sockets = optional(number, 1) # VMのCPUソケット数(default: 1)
memory_mb = number # VMのメモリ容量(MB)
os_disk_size_gb = number # VMのディスクサイズ(GB)
os_disk_storage = string # VMのディスクを保存するストレージ
net_bridge = string # VMのネットワークデバイスを接続するブリッジ
net_ip_address = string # VMのIPアドレス
net_subnet_cidr = string # VMのサブネットマスク
net_default_gw = string # VMのデフォルトゲートウェイ
ciuser = optional(string, "ubuntu") # VMのユーザー名
ssh_public_key = string # VMに登録するSSH公開鍵
}))
}
ubuntu_vm.tfの作成
VMのresourceを作成します。一度に複数のVMを作れるようにしたかったので、作成するVMのリストを渡せるようにしています。
resource "proxmox_vm_qemu" "ubunut_vm" {
count = length(var.vms)
vmid = var.vms[count.index].vmid
name = var.vms[count.index].name
desc = var.vms[count.index].description
target_node = var.pm_target_node
clone = var.vms[count.index].ubuntu_tmpl_name
agent = 1
os_type = "cloud-init"
boot = "order=virtio0"
tags = var.vms[count.index].tags
cpu {
cores = var.vms[count.index].cpu_cores
sockets = var.vms[count.index].cpu_sockets
type = "host"
}
memory = var.vms[count.index].memory_mb
scsihw = "virtio-scsi-single"
disks {
ide {
ide0 {
cloudinit {
storage = var.vms[count.index].os_disk_storage
}
}
}
virtio {
virtio0 {
disk {
size = var.vms[count.index].os_disk_size_gb
storage = var.vms[count.index].os_disk_storage
iothread = true
}
}
}
}
serial {
id = 0
type = "socket"
}
network {
id = 0
model = "virtio"
bridge = var.vms[count.index].net_bridge
}
ipconfig0 = "ip=${var.vms[count.index].net_ip_address}/${split("/", var.vms[count.index].net_subnet_cidr)[1]},gw=${var.vms[count.index].net_default_gw}"
ciuser = var.vms[count.index].ciuser
sshkeys = var.vms[count.index].ssh_public_key
}
output.tfの作成
出力をスッキリさせたかったので、VM名、IPアドレス、メモリ容量、vCPU数を表示するようにしてます。
output "vm_list" {
value = [
for idx, vm in var.vms : {
name = vm.name
ip_address = vm.net_ip_address
memory_mb = vm.memory_mb
vcpu = vm.cpu_cores * vm.cpu_sockets
}
]
}
terraform.tfvars
最後に設定ファイルを作成します。ここではVMを2つ作る設定ファイルにしています。
適用する環境に合わせて設定を変更します。
# Proxmoxの設定
pm_api_url = "https://<ProxmoxノードのIP>:8006/api2/json"
pm_api_token_id = "root@pam!terraform"
pm_api_token_secret = "aaaaaaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
pm_tls_insecure = true
pm_target_node = "pve"
pm_parallel = 2
pm_timeout = 600
# VMの設定
vms = [
{
vmid = 155
name = "ubuntu-vm-01"
description = "Ubuntu VM 01"
ubuntu_tmpl_name = "ubuntu-2404-tmpl"
cpu_cores = 3
cpu_sockets = 1
memory_mb = 2048
os_disk_size_gb = 20
os_disk_storage = "local-lvm"
net_bridge = "vmbr0"
net_ip_address = "192.168.50.184"
net_subnet_cidr = "192.168.50.0/24"
net_default_gw = "192.168.50.1"
ciuser = "ubuntu"
ssh_public_key = "ssh-rsa <SSH-PUBLIC-KEY-TEXT> ubuntu@pc"
}, {
vmid = 156
name = "ubuntu-vm-02"
description = "Ubuntu VM 02"
ubuntu_tmpl_name = "ubuntu-2404-tmpl"
cpu_cores = 2
cpu_sockets = 1
memory_mb = 2048
os_disk_size_gb = 20
os_disk_storage = "local-lvm"
net_bridge = "vmbr8"
net_ip_address = "192.168.8.185"
net_subnet_cidr = "192.168.8.0/24"
net_default_gw = "192.168.8.1"
ciuser = "ubuntu"
ssh_public_key = "ssh-rsa <SSH-PUBLIC-KEY-TEXT> ubuntu@pc"
},
]
VMを作成してみる
Terrafrom関連のファイルが作成できたので最後に適用します。なお、コマンドの出力を含めると長くなるのでここでは省略します
# モジュールなどを初期化
$ terraform init
# Terraformの実行計画を確認
$ terraform plan
# Proxmoxに適用(最後にoutput.tfで定義した形で出力されます)
$ terraform apply -auto-approve
...
Outputs:
vm_list = [
{
"ip_address" = "192.168.50.184"
"memory_mb" = 2048
"name" = "ubuntu-vm-01"
"vcpu" = 3
},
{
"ip_address" = "192.168.8.185"
"memory_mb" = 4096
"name" = "ubuntu-vm-02"
"vcpu" = 2
},
]
大変だったところ
知識が全くなかったので全体的に大変でしたが、ProxmoxのGUIからコンソールになかなかアクセスできず、解決までに無駄に時間を使ってしまいました。結果的に、ubuntu_vm.tf
にserial
ブロックを追加して解消できましたが、ずっとVM自体がスタックしていると勘違いして全然違うところ調べていました(早くpingを飛ばしてVMが起動しているか確認すればよかった...)
Discussion