首页 公告 项目 RSS

使用terraform创建pve虚拟机

August 14, 2023 本文有 1570 个字 需要花费 4 分钟阅读

简介

因为每次创建虚拟机都要点一大堆按钮,实在是过于麻烦,所以就想着使用 terraform 去自动化这一过程,下面说的是创建 alma linux 虚拟机的过程,其他的也都大差不差

创建虚拟机模板

首先需要下载镜像,这里需要下载带有 cloud init 的镜像,这样子可以方便后面添加虚拟机 ssh 公钥等操作

wget https://repo.almalinux.org/almalinux/8/cloud/x86_64/images/AlmaLinux-8-GenericCloud-latest.x86_64.qcow2

这里我选择的是 alma linux 8 其他的发型版本大部分也是提供相关镜像的

之后使用命令创建虚拟机,当然你直接使用控制面板创建也没有什么关系

qm create 100 --name alma8-cloudinit --onboot 1 --cores 2 --memory 2048 --net0 virtio,bridge=vmbr0

这里的100代表的是虚拟机 id --onboot 1表示当宿主机重启之后,虚拟机自动启动,--net0 virtio,bridge=vmbr0这里指定虚拟网卡

之后导入磁盘

qm disk import 100 AlmaLinux-8-GenericCloud-latest.x86_64.qcow2 vm

最后的 vm 代表的是磁盘存储池的名字

查看磁盘 id

qm config 100

boot: order=net0
cores: 2
memory: 2048
meta: creation-qemu=8.0.2,ctime=1691981152
name: alma8-cloudinit
net0: virtio=0A:52:1C:99:19:1A,bridge=vmbr0
onboot: 1
smbios1: uuid=a8b99174-7b38-4950-a7ef-bf1dfa4174d0
unused0: vm:vm-100-disk-0
vmgenid: c7004b83-9803-4a5b-8c55-94b7618a00b6

上面显示我们刚才导入的磁盘还没有被使用,我们需要把它配置到scsi0上

配置磁盘

qm set 100 --scsihw virtio-scsi-pci --scsi0 vm:vm-100-disk-0

这里注意scsihw 最好选择virtio-scsi-pci不然启动可能会报错

默认是网络 pxe 启动,所以我们需要把这个磁盘设置为启动盘

qm set 100 --boot c --bootdisk scsi0

配置使用 cloudinit

qm set 100 --ide2 vm:cloudinit

使用qemu-guest-agent功能

qm set 100 --agent 1

最后确认下虚拟机配置

qm config 100

agent: 1
boot: c
bootdisk: scsi0
cores: 2
ide2: vm:vm-100-cloudinit,media=cdrom
memory: 2048
meta: creation-qemu=8.0.2,ctime=1691981152
name: alma8-cloudinit
net0: virtio=0A:52:1C:99:19:1A,bridge=vmbr0
onboot: 1
scsi0: vm:vm-100-disk-0,size=10G
scsihw: virtio-scsi-pci
smbios1: uuid=a8b99174-7b38-4950-a7ef-bf1dfa4174d0
vmgenid: c7004b83-9803-4a5b-8c55-94b7618a00b6

如果没有什么特别大的问题的话,这个时候我们就可以把它转换成模板

qm template 100

使用terraform创建虚拟机

模板创建完成之后,我们就可以用terraform去创建我们想要的虚拟机了

首先我们需要安装terraform

brew install terraform

之后初始化项目

编写main.tf

terraform {
  required_providers {
    proxmox = {
      source  = "telmate/proxmox"
      version = "2.9.14"
    }
  }
}

provider "proxmox" {
  # Configuration options
}

这里version我指定的是我目前最新的proxmox provider

如果你要使用最新的话可以看

https://github.com/Telmate/terraform-provider-proxmox

编写完成之后保存,然后执行

terraform init

如果有下面的输出,就表示这个provider已经安装完成,项目也已经初始化完成了


Initializing the backend...

Initializing provider plugins...
- Finding telmate/proxmox versions matching "2.9.14"...
- Installing telmate/proxmox v2.9.14...
- Installed telmate/proxmox v2.9.14 (self-signed, key ID A9EBBE091B35AFCE)

Partner and community providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:
https://www.terraform.io/docs/cli/plugins/signing.html

Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

接着需要配置 provider


provider "proxmox" {
  pm_api_url      = "https://xxxxxxxxx:8006/api2/json" # 定义 api 的地址,就是 pve 的地址
  pm_user         = "root@pam" # pve 的用户记得带上@pam
  pm_password     = "xxxxxxx" # 密码
  pm_tls_insecure = "true" # 是不是需要禁用 tls 验证
}

proxmox支持两种认证方式,一种是账号密码,另外一种就是创建api token,如果你选择创建 api token 的方式的话,需要给 token授权,这个授权权限给的貌似有点多,所以我就懒得操作了,直接使用了用户名密码,其他provider详细的参数可以看下面

https://registry.terraform.io/providers/Telmate/proxmox/latest/docs

最后就是重头戏配置虚拟机资源,详细的参数可以看

https://registry.terraform.io/providers/Telmate/proxmox/latest/docs/resources/vm_qemu

我的配置在下面,重要的都在注释里面了

resource "proxmox_vm_qemu" "test" {
  name            = "test" # 虚拟机名字
  target_node     = "pve" # 虚拟机要部署的物理节点
  clone           = "alma8-cloudinit" # 从什么模板 clone
  full_clone      = "true" # 是不是完整 clone,默认是链接 clone
  onboot          = "true" # pve 节点启动之后是不是自动启动
  memory          = "4096" # 内存大小
  numa            = "true" # 启用非统一内存访问,如果你配置了热插拔,这里要配置为 true
  scsihw          = "virtio-scsi-pci" # 要模拟的 SCSI 控制器
  cores           = "4" # cpu核心数
  hotplug         = "cpu,memory" # 开启支持热插拔的资源
  nameserver      = "10.10.100.1" # 虚拟机的dns 服务器
  ciuser          = "root" # 虚拟机的用户
  sshkeys         = <<EOF 
xxxxxxxxxxxxxxxxxxxxx # 这里写虚拟机的公钥
EOF
  disk { # 磁盘配置
    type    = "scsi" # 磁盘类型
    size    = "50G" # 磁盘大小
    storage = "vm" # 用于存储磁盘存储池的名字
  }

  ipconfig0 = "ip=10.10.100.252/24,gw=10.10.100.1" # 网络 ip 的配置
}

最后整体看下main.tf


terraform {
  required_providers {
    proxmox = {
      source  = "telmate/proxmox"
      version = "2.9.14"
    }
  }
}

provider "proxmox" {
  pm_api_url      = "https://xxxxxxxxx:8006/api2/json"
  pm_user         = "root@pam"
  pm_password     = "xxxxxxxxxxxxx"
  pm_tls_insecure = "true"
}

resource "proxmox_vm_qemu" "test" {
  name            = "test"
  target_node     = "pve"
  clone           = "alma8-cloudinit"
  full_clone      = "true"
  onboot          = "true"
  memory          = "4096"
  numa            = "true"
  scsihw          = "virtio-scsi-pci"
  cores           = "4"
  hotplug         = "cpu,memory"
  nameserver      = "10.10.100.1"
  ciuser          = "root"
  sshkeys         = <<EOF
xxxxxxxxxxxxxxxxxxxx
EOF
  disk {
    type    = "scsi"
    size    = "50G"
    storage = "vm"
  }

  ipconfig0 = "ip=10.10.100.252/24,gw=10.10.100.1"
}

写完之后可以格式化下

terraform fmt

验证下文件

terraform validate

如果没有什么问题的话就可以 apply 了

terraform apply

如果有问题,或者什么参数不对,可以多次 apply

欢迎关注我的博客www.bboy.app

Have Fun