はじめに
前回 Proxmox VEとTerraformでインターン生に仮想マシンを払い出す話 という記事を書きました。
最初はインターンシップのために始めてみたけど、案外利用シーンが多かったりして。
そんなこんなで、簡単にVMが提供できるようになったら、どんどんVMが作っては捨てられていきます。
すると、今度はIPアドレスの管理が行き届かなくなりました。
VMを作る度にExcelシートを更新していたら、大変です。
そこで、TerraformでVMを作るついでに、IPAMツールである Netbox にもIPアドレスを登録できるようにしてみましょう。
サンプル用のNetboxの構築
Netboxにはdockerイメージがありますので、この記事用に構築してみます。
https://github.com/netbox-community/netbox-docker のQuickStartにならって、以下のコマンドで起動します。
手元の環境がDocker compose v2だったので docker-compose
コマンドは docker compose
に読み替えています。
git clone -b release https://github.com/netbox-community/netbox-docker.git
cd netbox-docker
tee docker-compose.override.yml <<EOF
version: '3.4'
services:
netbox:
ports:
- 8000:8080
EOF
echo "VERSION=v3.4.4-2.4.0" > .env
docker compose pull
docker compose up -d
.env
ファイルでバージョンを指定しているのはTerraform Providerのサポートバージョンと合わせるためです。
少し待つと admin
/ admin
でログインするところまで進みました。
特に引っ掛かりは無いと思いますが、netbox-dockerではdocker composeのhealthcheckが動いているため、Netboxの起動時の初期化が遅いと container netbox-docker-netbox-1 is unhealthy
と出力されることがあります。
$ docker compose up -d
[+] Running 3/4
⠿ Container netbox-docker-redis-cache-1 Running 0.0s
⠿ Container netbox-docker-postgres-1 Running 0.0s
⠿ Container netbox-docker-redis-1 Running 0.0s
⠿ Container netbox-docker-netbox-1 Error 0.5s
dependency failed to start: container netbox-docker-netbox-1 is unhealthy
そうなった場合は docker compose logs -f netbox
でログを拾ってみましょう。
初期化の途中であれば、少し待ってから再度 docker compose up -d
実行することで解決します。
Terafform Netbox Provider
TerraformでNetboxを扱うためのNetbox Providerは、どうやらCommunityで作成された有力なものが2つあるようです。
- https://registry.terraform.io/providers/e-breuninger/netbox/latest/docs -> Github
- https://registry.terraform.io/providers/smutel/netbox/latest/docs -> Github
特に選定理由があるわけでもありませんので、今回は1つ目の方(e-breuninger/netbox)を試してみます。
Netbox用のtfファイルの作成
Proxmox VEとTerraformでインターン生に仮想マシンを払い出す話 で使用したtfファイルを編集して、VMが使用するIPアドレスをNetboxに登録するようにしてみます。
変更点は以下の通りです。
- providerに
e-breuninger/netbox 3.1.0
を追加 - netboxの接続情報を追加
- api_token は https://github.com/netbox-community/netbox-docker#quickstart に書いてある通りです
- netbox_ip_address のリソースを追加
前回作成したファイルに以下の差分を追記します。(全文は記事下部に記載)
--- a/intern-vm.tf
+++ b/intern-vm.tf
@@ -11,6 +11,10 @@ terraform {
source = "telmate/proxmox"
version = "2.9.11"
}
+ netbox = {
+ source = "e-breuninger/netbox"
+ version = "3.1.0"
+ }
}
}
@@ -21,6 +25,11 @@ provider "proxmox" {
pm_tls_insecure = true
}
+provider "netbox" {
+ server_url = "http://netbox.example.com:8000"
+ api_token = "0123456789abcdef0123456789abcdef01234567"
+}
+
resource "proxmox_vm_qemu" "intern-vm" {
name = "intern-vm-${var.username}"
target_node = "pve-c01"
@@ -46,3 +55,8 @@ ${var.public_key}
EOF
}
+
+resource "netbox_ip_address" "intern_vm_eth0_ip" {
+ ip_address = "${var.ip_address}/24"
+ status = "active"
+}
Terraformの実行前確認
Providerのインストールをして、planに問題なさそうかを確認します。
terraform init -upgrade
terraform plan -var-file sample01.tfvars
Netboxのバージョンが新しく、Terraform Providerがサポート範囲外となる場合は以下のように警告が出ます。
╷
│ Warning: Possibly unsupported Netbox version
│
│ with provider["registry.terraform.io/e-breuninger/netbox"],
│ on intern-vm.tf line 28, in provider "netbox":
│ 28: provider "netbox" {
│
│ Your Netbox version is v3.4.5. The provider was successfully tested against the following versions:
│
│ 3.3.0, 3.3.1, 3.3.2, 3.3.3, 3.3.4, 3.3.5, 3.3.6, 3.3.7, 3.3.8, 3.3.9, 3.3.10, 3.4.0, 3.4.1, 3.4.2, 3.4.3, 3.4.4
│
│ Unexpected errors may occur.
╵
この記事の手順通りの場合、冒頭でNetboxのバージョンに v3.4.4
を明示したので警告は出ないと思います。
と言っても、v3.4.4とv3.4.5ではAPI仕様にそう大きな変更は無いでしょうから、警告を無視して利用する判断もあるかと思います。
Terraformの実行とログ
それでは terraform plan
が成功したら、早速実行してみましょう。
Terraformで仮想マシンを作成するのと同時に、IPアドレスがNetboxに登録されるはずです。
$ 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:
# netbox_ip_address.intern_vm_eth0_ip will be created
+ resource "netbox_ip_address" "intern_vm_eth0_ip" {
+ id = (known after apply)
+ ip_address = "192.168.0.11/24"
+ object_type = "virtualization.vminterface"
+ status = "active"
}
# 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: 2 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
netbox_ip_address.intern_vm_eth0_ip: Creating...
proxmox_vm_qemu.intern-vm: Creating...
netbox_ip_address.intern_vm_eth0_ip: Creation complete after 0s [id=1]
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 1m5s [id=pve-c01/qemu/103]
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
実行結果の確認
Proxmox VEでは、仮想マシンが作成されて起動しています。
root@pve-c01:~# pvesh get /nodes/pve-c01/qemu/103/status/current
┌─────────────────┬────────────────────┐
│ key │ value │
╞═════════════════╪════════════════════╡
│ cpus │ 4 │
├─────────────────┼────────────────────┤
│ ha │ {"managed":0} │
├─────────────────┼────────────────────┤
│ maxdisk │ 120.00 GiB │
├─────────────────┼────────────────────┤
│ maxmem │ 8.00 GiB │
├─────────────────┼────────────────────┤
│ name │ intern-vm-sample01 │
├─────────────────┼────────────────────┤
│ pid │ 817200 │
├─────────────────┼────────────────────┤
│ qmpstatus │ running │
├─────────────────┼────────────────────┤
│ running-machine │ pc-i440fx-7.2+pve0 │
├─────────────────┼────────────────────┤
│ running-qemu │ 7.2.0 │
├─────────────────┼────────────────────┤
│ status │ running │
├─────────────────┼────────────────────┤
│ uptime │ 6m 17s │
├─────────────────┼────────────────────┤
│ vmid │ 103 │
└─────────────────┴────────────────────┘
Netboxにも、IPアドレスが登録されていることが確認できました。
もちろん、削除も terraform destroy -var-file sample01.tfvars
で簡単です。
おしまい
今回はProxmox VEとTerraformにNetboxを追加で組み合わせて、VMを作る時にIPアドレスをNetboxに登録する方法を書いてみました。
手元の機材を使うと、どうしても管理しなければならない点が増えてしまいます。しかし、ネットワークサービスを始めとした自社設備の管理が重要となる業界では、現在でもこういった情報の同期が必要なケースもありますので、上手く使ってみてください。
付録
差分ではなく、使用したtfファイル全文もこちらに掲載しておきます。
intern-vm.tf
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"
}
netbox = {
source = "e-breuninger/netbox"
version = "3.1.0"
}
}
}
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
}
provider "netbox" {
server_url = "http://netbox.example.com:8000"
api_token = "0123456789abcdef0123456789abcdef01234567"
}
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
}
resource "netbox_ip_address" "intern_vm_eth0_ip" {
ip_address = "${var.ip_address}/24"
status = "active"
}