Aller au contenu principal

OpenTofu - Création de plusieurs VM

1. Création de plusieurs VM avec OpenTofu​

1.1. Arborescence du projet tofu​

tofu
├── modules
│ └── proxmox
│ ├── README.md
│ ├── main.tf
│ ├── provider.tf
│ └── variables.tf
└── stacks
├── README.md
├── vm1
│ └── main.tf
├── vm2
│ └── main.tf
└── vm3
└── main.tf

2. Création du module tofu proxmox​

  • On va créer un module proxmox pour factoriser le code de création d'une VM

2.1. Créer le répertoire modules/proxmox​

$ mkdir -p modules/proxmox

2.2. Créer le fichier modules/proxmox/main.tf​

modules/proxmox/main.tf
# file: main.tf

# https://registry.terraform.io/providers/bpg/proxmox/latest/docs/resources/virtual_environment_vm
resource "proxmox_virtual_environment_vm" "almalinux_vm" {
# Proxmox node
node_name = var.target_node

# VM
name = "${var.vm_hostname}.${var.vm_domain}"
description = "Managed by OpenTofu"
tags = var.vm_tags
clone {
vm_id = var.vm_clone_vm_id
full = true
}
on_boot = var.vm_on_boot
started = var.vm_started
reboot = var.vm_reboot
reboot_after_update = var.vm_reboot_after_update

# VM Options
operating_system {
type = var.vm_operating_system_type
}
agent {
enabled = var.vm_agent_enabled
}

# VM Memory
memory {
dedicated = var.vm_memory
}
# VM Processors
cpu {
sockets = var.vm_cpu_sockets
cores = var.vm_cpu_cores
type = var.vm_cpu_type
numa = var.vm_cpu_numa
}
# VM BIOS
bios = "seabios"
# VM Disk Settings
scsi_hardware = "virtio-scsi-single"
# VM Network Device Settings
network_device {
bridge = "vmbr0"
model = "virtio"
firewall = true
}
lifecycle {
ignore_changes = [
network_device,
]
}
initialization {
datastore_id = var.vm_datastore_id
ip_config {
ipv4 {
address = var.vm_ipv4_address
gateway = var.vm_ipv4_gateway
}
}
interface = "ide2"
}
}

2.3. Créer le fichier modules/proxmox/provider.tf​

modules/proxmox/provider.tf
terraform {
required_providers {
proxmox = {
source = "bpg/proxmox"
version = "0.77.1"
}
}
}

provider "proxmox" {
endpoint = var.pm_endpoint
api_token = var.pm_api_token
insecure = false
ssh {
agent = true
username = "root"
#private_key = file("/.ssh/bootstrap")
}
}

2.4. Créer le fichier modules/proxmox/variables.tf​

modules/proxmox/variables.tf
variable "pm_endpoint" {
type = string
default = "https://pve1.home.lab:8006/"
}

variable "pm_ssh_username" {
type = string
default = "root"
}

variable "target_node" {
type = string
default = "pve1"
}

variable "target_node_domain" {
description = "Proxmox node domain"
type = string
default = "home.lab"
}

variable "vm_additionnal_disks" {
description = "Additionnal disks"
type = list(object({
storage = string
size = number
}))
default = []
}

variable "vm_agent_enabled" {
type = bool
default = true
}

variable "vm_bios" {
type = string
default = "seabios"
}

variable "vm_clone_vm_id" {
type = number
default = 10001
}

variable "vm_cpu_cores" {
description = "The number of CPU cores"
type = number
default = 2
}

variable "vm_cpu_numa" {
description = "Enable/disable NUMA"
type = bool
default = false
}

variable "vm_cpu_sockets" {
description = "The umber of CPU sockets"
type = number
default = 1
}

variable "vm_cpu_type" {
description = "The emulated CPU type"
type = string
default = "x86-64-v2-AES"
}

variable "vm_datastore_id" {
description = "The identifier for the datastore to create the cloud-init disk"
type = string
default = "local"
}

variable "vm_disk" {
description = "Disk (size in Gb)"
type = object({
storage = string
size = number
})
default = {
storage = "gv0"
size = 10
}
}

variable "vm_domain" {
description = "VM domain"
type = string
default = "home.local"
}

variable "vm_hostname" {
description = "VM hostname"
type = string
default = "test"
}

variable "vm_ipv4_address" {
description = "IPv4 address"
type = string
default = ""
}

variable "vm_ipv4_gateway" {
description = "IPv4 gateway"
type = string
default = "192.168.50.201"
}

variable "vm_memory" {
description = "Number of memory in MB"
type = number
default = 2048
}

variable "vm_on_boot" {
description = "Auto start VM when node is start"
type = bool
default = false
}

variable "vm_operating_system_type" {
type = string
default = "l26"
}

variable "vm_reboot" {
type = bool
default = false
}

variable "vm_reboot_after_update" {
type = bool
default = false
}

variable "vm_started" {
type = bool
default = true
}

variable "vm_tags" {
description = "VM tags"
type = list(string)
default = [ "opentofu", "almalinux9" ]
}

2.5. Créer le fichier stacks/vm1/main.tf​

  • Maintenant que le module est créé, il suffit juste de déclarer les variables personnalisées pour chaque VM, par exemple la vm1 :
stacks/vm1/main.tf
module "vm1" {
# module proxmox
source = "../../modules/proxmox"
# tofu
vm_hostname = "vm1"
vm_domain = "home.lab"
vm_tags = [ "almalinux9", "demo" ]
# cloud-init
vm_ipv4_address = "192.168.50.101/24"
vm_ipv4_gateway = "192.168.50.201"
}
  • De même, créer un fichier pour les autres VM, par exemple la vm2 :
stacks/vm2/main.tf
module "vm2" {
# module proxmox
source = "../../modules/proxmox"
# tofu
vm_hostname = "vm2"
vm_domain = "home.lab"
vm_tags = [ "almalinux9", "demo" ]
# cloud-init
vm_ipv4_address = "192.168.50.102/24"
vm_ipv4_gateway = "192.168.50.201"
}

3. Provisionnement des VM sur Proxmox​

  • Aller dans le dossier d'une des VM, par exemple pour la vm1 :
$ cd stacks/vm1

3.1. Initialisation : tofu init​

$ tofu init

3.2. Vérification de la planification : tofu plan​

$ tofu plan

3.3. Déploiement de la planification sur Proxmox : tofu apply​

$ tofu apply

4. Ressources​