4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Proxmox VEとTerraformにNetboxを加えて仮想マシンとIPをセットで管理する話

Last updated at Posted at 2023-03-08

はじめに

前回 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 でログインするところまで進みました。

image.png

特に引っ掛かりは無いと思いますが、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つあるようです。

特に選定理由があるわけでもありませんので、今回は1つ目の方(e-breuninger/netbox)を試してみます。

Netbox用のtfファイルの作成

Proxmox VEとTerraformでインターン生に仮想マシンを払い出す話 で使用したtfファイルを編集して、VMが使用するIPアドレスをNetboxに登録するようにしてみます。
変更点は以下の通りです。

前回作成したファイルに以下の差分を追記します。(全文は記事下部に記載)

--- 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アドレスが登録されていることが確認できました。

image.png

もちろん、削除も 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"
}
4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?