使用 Terraform 来管理创建 PVE 中的虚拟机

✨ 使用 Terraform 在 PVE 中管理虚拟机,实现基础设施即代码(IaaS)。通过配置 Terraform 的 provider,使用 PVE 的 REST API 进行权限校验。可以通过用户名密码或 API Token 来鉴权。配置虚拟机资源的核心参数,包括基础信息、物理节点、cloud-init 模板、CPU、内存、磁盘、网络等。执行 terraform apply 即可创建虚拟机。如果需要销毁虚拟机,执行 terraform destroy 即可。

TOC

👉 在上一步中,已经安装好了 PVE,并配置了 debian-12-cloud-init 的 基础系统模板。

https://note.okhk.net/my-homelab-powered-by-pve-install

简介

Terraform 是一种基础设施即代码(IaC)工具,用于创建、更改和管理云基础设施资源。
它允许开发人员使用代码来预置和支持托管基础设施,解决了手动预置基础设施组件的困难和耗时问题。其使用一种名为 HashiCorp 配置语言(HCL)的特定领域语言来编写声明式配置文件。它还提供了自动化基础设施变更管理的机制,支持多云部署,并拥有活跃的开发人员社区。
与Kubernetes相比,Terraform的抽象级别更高,管理云环境中的资源及其配置,而Kubernetes专注于集群中容器的部署和生命周期。

借助 terraform-provider-proxmox 项目,可以在PVE中实现自动化快速创建虚拟机,省去繁杂的页面操作。

使用

安装配置

# macOS
brew install terraform
  • 编写 main.tf 文件以初始化项目
terraform {
  required_providers {
    proxmox = {
      source  = "telmate/proxmox"
      version = "2.9.14"
    }
  }
}

provider "proxmox" {
  # Configuration options
}

保存,执行terraform init ,如出现如下图所示即为初始化完成。

  • 配置 provider

使用 PVE 的 REST API 是需要权限校验的,可以通过用户名密码或 API Token 两种方式来鉴权,任选其一即可。

先登录到 PVE 宿主机执行命令创建好相应的角色、用户及 API Token:

# 创建角色
pveum role add TerraformProv -privs "Datastore.AllocateSpace Datastore.Audit Pool.Allocate Sys.Audit Sys.Console Sys.Modify VM.Allocate VM.Audit VM.Clone VM.Config.CDROM VM.Config.Cloudinit VM.Config.CPU VM.Config.Disk VM.Config.HWType VM.Config.Memory VM.Config.Network VM.Config.Options VM.Migrate VM.Monitor VM.PowerMgmt SDN.Use"
# 创建用户
pveum user add terraform-prov@pve --password <password>
# 分配角色
pveum aclmod / -user terraform-prov@pve -role TerraformProv
# 创建 API Token
pveum user token add terraform-prov@pve terraform-token --privsep=0

用户名密码配置:

provider "proxmox" {
	# 是否禁用 TLS 验证
  pm_tls_insecure = "true"
	# API 地址,也就是 PVE 的管理路径
  pm_api_url      = "https://192.168.31.2:8006/api2/json"
	# 用户名
  pm_user         = "terraform-prov@pve"
	# 密码
  pm_password     = "password"

}

API Token 配置:

provider "proxmox" {
  pm_tls_insecure     = true
  pm_api_url          = "https://192.168.31.2:8006/api2/json"
	# 对应前面得到的 full-tokenid
  pm_api_token_id     = "terraform-prov@pve!terraform-token"
	# 对应 value
  pm_api_token_secret = "3be2ecd1-a04f-4542-8353-2915e6793120"

}
  • 配置虚拟机资源

这里是创建虚拟机的核心配置,详细参数说明可参阅

https://github.com/Telmate/terraform-provider-proxmox/blob/master/docs/resources/vm_qemu.mdhttps://registry.terraform.io/providers/Telmate/proxmox/latest/docs/resources/vm_qemu
resource "proxmox_vm_qemu" "proxmox-debian" {
  count = 1
  # 基础信息
  name = "debian-${count.index + 101}"
  desc = "Debian virtual machine"

  # 目标物理节点名
  target_node = "pve"

  # cloud-init 模板
  clone   = "debian-12-cloudinit-template"
  os_type = "cloud-init"

  scsihw = "virtio-scsi-pci"
  bootdisk = "scsi0"

  # cpu
  cores   = 2
  sockets = 1

  # memory
  memory  = 4096
  numa    = true
  balloon = 0

  # disk
  disk {
    type     = "scsi"
    size     = "20G"
    storage  = "local-lvm"
    iothread = 1
  }

  # network
  network {
    model  = "virtio"
    bridge = "vmbr0"
  }
  ipconfig0  = "ip=192.168.31.2${count.index + 1}/24,gw=192.168.31.1"

  # qemu guest agent
  agent  = 1
  onboot = true

  lifecycle {
    ignore_changes = [
      network,
    ]
  }
  
  # user
  ciuser          = "hk"
  sshkeys         = <<EOF
  ssh-ed25519 SSH-Publc-Key
  EOF

}

以上已经完成了 terraform 文件的编写。

创建虚拟机

执行 terraform fmt和terraform validate对上面编写的 main.tf 文件进行格式化和校验,校验通过没什么问题的话就可以执行terraform apply并输入 yes 开始创建虚拟机了

因 PVE API变动,此 provider 会产生错误,如下
Stack trace from the terraform-provider-proxmox_v2.9.14 plugin:
panic: interface conversion: interface {} is string, not float64

可使用第三方 Fork 的修复过后的 provider

terraform {
  required_providers {
    proxmox = {
      # source  = "telmate/proxmox"
      # version = "2.9.14"
      source  = "thegameprofi/proxmox"
      version = ">= 2.9.15"
    }
  }
}

销毁虚拟机

执行 terraform destroy 再输入 yes 即可

参考致谢

https://www.bboy.app/2023/08/14/使用terraform创建pve虚拟机/https://atbug.com/deploy-vm-on-proxmox-with-terraform/