使用terraform为proxmox创建虚拟机
目录
背景#
目前的工作对虚拟化和cloud native技术使用的比较多。搭建新的homelab节点,也希望将这些技术应用到日常的家庭服务器的管理中。
Iac的实践从terraform开始,使用terraform管理proxmox虚拟机,可以提高虚拟机创建和配置的效率,方便后续的维护和扩展。
采用的工具#
- Proxmox VE 9.0
- Terraform v1.15.0-dev - build from source
- Proxmox Terraform Provider - bpg/proxmox-v0.8.5
网络配置#
我使用的机器是老旧的laptop,只有无线网卡,没有有线网卡。已经解决了wifi连接的问题,参考安装proxmox的wifi问题及解决方法。
但是虚拟机的网络配置需要额外处理。
默认情况下,Proxmox VE使用vmbr0作为桥接网络接口,将虚拟机连接到物理网络。然而,在只有无线网卡的情况下,桥接网络可能无法正常工作。为了解决这个问题,我们可以使用NAT(网络地址转换)来为虚拟机提供网络连接。
修改Proxmox的网络配置文件/etc/network/interfaces,添加NAT配置:
auto lo
iface lo inet loopback
auto wlp1s0
iface wlp1s0 inet static
address 192.168.50.3/24
gateway 192.168.50.1
wpa-ssid xxx
wpa-psk xxx
# 启用 IP 转发,允许 wlp1s0 路由来自 vmbr0 的流量
post-up echo 1 > /proc/sys/net/ipv4/ip_forward
# 设置 NAT 规则:将所有来自 vmbr0 的流量进行地址伪装后,通过 wlp1s0 发送
post-up iptables -t nat -A POSTROUTING -s '10.10.10.0/24' -o wlp1s0 -j MASQUERADE
post-down iptables -t nat -D POSTROUTING -s '10.10.10.0/24' -o wlp1s0 -j MASQUERADE
# **********************************************
# 2. 配置 Bridge 接口 (vmbr0) - 供 VM 使用的私有网络
# **********************************************
auto vmbr0
iface vmbr0 inet static
# 为 vmbr0 设置一个完全不同的私有 IP 网段 (例如 10.10.10.1/24)
address 10.10.10.1/24
# vmbr0 没有物理端口,因为它不直接桥接 Wi-Fi
bridge-ports none
bridge-stp off
bridge-fd 0
source /etc/network/interfaces.d/*
配置完成后,重启网络服务:
systemctl restart networking
这样,虚拟机可以通过NAT访问外部网络,而不依赖于桥接网络。
Terraform#
Terraform安装#
这里使用的是从源码编译的terraform,版本是v1.15.0-dev。
apt install golang
git clone https://github.com/hashicorp/terraform
cd terraform
go install
# move terraform binary to where is included in $PATH
mv ~/go/bin/terraform /usr/local/bin/
# install the autocomplete package.
terraform -install-autocomplete
Proxmox Provider安装#
terraform {
required_providers {
proxmox = {
source = "bpg/proxmox"
version = "0.85.1"
}
}
}
provider "proxmox" {
insecure = true // necessary because of self-signed certificates
}
我的terraform跑在远程的服务器上,所以可以通过环境变量传递proxmox的连接信息:
export PROXMOX_VE_ENDPOINT="https://192.168.50.3:8006"
export PROXMOX_VE_USERNAME="root@pam"
export PROXMOX_VE_PASSWORD="your_password"
更好的方式是使用API token进行认证。可以查看官方文档Proxmox Terraform docs了解更多配置选项。
下载image#
在proxmox中创建虚拟机之前,需要先下载操作系统的image。 这里使用的是Ubuntu 24.04 server的cloud image。
image.tf:
resource "proxmox_virtual_environment_download_file" "ubuntu_cloud_image" {
content_type = "iso"
datastore_id = "iso-templates"
node_name = "pve"
url = "https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img"
file_name = "ubuntu-24.04-noble-cloudimg.img"
}
iso-templates是我在proxmox中创建的一个datastore,用于存放iso和image文件。实际存储在一个NFS存储上。

将image下载单独成一个tf文件,这样可以避免每次创建虚拟机都重新下载image。
创建虚拟机#
main.tf:
# Create Ubuntu VM
resource "proxmox_virtual_environment_vm" "ubuntu_vm" {
name = "ubuntu"
node_name = "pve"
machine = "q35"
bios = "ovmf"
# should be true if qemu agent is not installed / enabled on the VM
stop_on_destroy = true
initialization {
ip_config {
ipv4 {
address = "dhcp"
}
}
user_account {
username = var.vm_user
password = var.vm_password
}
}
network_device {
bridge = "vmbr0"
}
cpu {
cores = var.vm_cores
}
memory {
dedicated = var.vm_memory
}
serial_device {}
efi_disk {
datastore_id = "local-lvm"
}
disk {
datastore_id = "local-lvm"
file_id = proxmox_virtual_environment_download_file.ubuntu_cloud_image.id
interface = "virtio0"
iothread = true
discard = "on"
size = 100
}
}
Makefile#
执行terraform的命令比较多,可以使用Makefile简化操作。(从上一份golang的工作开始,Makefile就成了我的project的标配)
# Init
init: create-tfvars
terraform init
# Plan: image download
create-tfvars:
cp terraform.tfvars.example terraform.tfvars
plan-image:
terraform plan -out=image.plan -target=proxmox_virtual_environment_download_file.ubuntu_cloud_image
# Apply: image download
apply-image: plan-image
terraform apply "image.plan"
# Plan: VM creation
plan-vm:
terraform plan -out=vm.plan -target=proxmox_virtual_environment_vm.ubuntu_vm
# Apply: VM creation
apply-vm: plan-vm
terraform apply "vm.plan"
# Destroy - destroy all resources
destroy:
terraform destroy
# Clean - remove local terraform files
clean:
rm -rf .terraform/
rm -f .terraform.lock.hcl
rm -f *.tfstate*
rm -f *.plan
# destry vm only
destroy-vm:
terraform destroy -target=proxmox_virtual_environment_vm.ubuntu_vm
# destroy image only
destroy-image:
terraform destroy -target=proxmox_virtual_environment_download_file.ubuntu_cloud_image
执行#
make init
make apply-image
make apply-vm
源码#
source code可以看这里
总结#
使用terraform为proxmox创建虚拟机,可以大大简化虚拟机的创建和配置过程,提高效率。通过NAT配置,可以解决无线网卡环境下虚拟机的网络连接问题。未来可以进一步完善多虚拟机的管理和自动化部署,以及terraform state的管理。