Déployer une VM sur Proxmox avec Terraform

Dans un précédent tutoriel (disponible ici), nous avons vu comment utiliser Packer pour créer un template Rocky Linux sur Proxmox. Ce template sert désormais de base pour toutes nos machines virtuelles.

Dans cet article, nous allons passer à l’étape suivante et utiliser Terraform pour automatiser la création de nos VMs. L’approche Infrastructure as Code (IaC) est idéale pour automatiser, standardiser et versionner nos infrastructures.

Terraform permet de gérer l’infrastructure via des fichiers de configuration en texte brut, remplaçant ainsi les actions manuelles effectuées via des interfaces graphiques (GUI). Cette approche facilite l’automatisation, la reproductibilité et la collaboration.

Avant de commencer, vous aurez besoin de :

  • Un template Proxmox : Si vous ne l’avez pas encore créé, suivez mon tutoriel ici pour générer un template Rocky Linux, ou bien utilisez une image ISO de Rocky Linux disponible ici.
  • Terraform installé : Assurez-vous que Terraform est configuré sur votre machine locale.

Avant d’utiliser Terraform pour déployer une VM, vous devez créer un utilisateur et une clé API pour que Terraform puisse interagir avec Proxmox sans nécessiter d’accès SSH direct. Voici les étapes détaillées pour cette configuration.

Il est recommandé de créer un utilisateur dédié pour l’API Proxmox avec un token d’authentification plutôt qu’un mot de passe classique. Exécutez cette commande pour ajouter un nouvel utilisateur :

bash

pveum useradd terraform@pve -password ${PASSWORD}

Pour interagir avec l’API Proxmox, vous devez générer un token d’API. Exécutez cette commande pour créer un token API :

bash

pveum user token add terraform@pve terraform --comment "Terraform API Token"

Pour plus d’information sur les tokens, voir ici.

Ensuite, créez un rôle personnalisé avec des permissions spécifiques pour Terraform, en utilisant cette commande :

bash

 pveum roleadd TerraformRole -privs "Datastore.AllocateSpace Datastore.Allocat
eTemplate Datastore.Audit Pool.Allocate Sys.Audit Sys.Console Sys.Modify VM.Allocate VM.Au
dit VM.Clone VM.Config.CDROM VM.Config.Cloudinit VM.Config.CPU VM.Config.Disk VM.Config.HW
Type VM.Config.Memory VM.Config.Network VM.Config.Options VM.Migrate VM.Monitor VM.PowerMg
mt SDN.Use"

Pour plus d’information sur les permissions, voir ici.

Enfin, attribuez le rôle TerraformRole à l’utilisateur terraform@pve ainsi qu’à son token terraform@pve!terraform pour lui accorder les permissions nécessaires :

bash

pveum aclmod / -user terraform@pve -role TerraformRole
pveum aclmod / --roles TerraformRole --token 'terraform@pve!terraform' --propagate 1

Voici la structure de base de votre projet Terraform, qui consiste en trois fichiers principaux :

plaintext

.
├── main.tf
├── providers.tf
├── variables.tf
├── terraform.tfvars

Ce fichier configure le fournisseur Proxmox pour Terraform et définit les informations d’authentification via le token API.

hcl

terraform {
  required_version = ">= 0.15"
  required_providers {
    proxmox = {
      source  = "Telmate/proxmox"
      version = "3.0.1-rc6"
    }
  }
}

provider "proxmox" {
  pm_api_url      = "https://proxmox-serveur:8006/api2/json"
  pm_tls_insecure = true
}

Ce fichier contient toutes les variables nécessaires pour rendre votre configuration Terraform flexible et facile à personnaliser. Grâce à ces variables, vous pouvez ajuster des éléments comme le nom de la VM, les ressources allouées, ou encore les paramètres réseau, sans modifier directement le code.

hcl

variable "vm_name" {
  description = "Le nom de la VM"
  type        = string
  default     = null
}

variable "target_node" {
  description = "Le nom du noeud Proxmox où déployer la VM"
  type        = string
  default     = null
}

variable "template_name" {
  description = "Le nom du template à utiliser pour créer la VM"
  type        = string
  default     = null
}

variable "cores" {
  description = "Le nombre de cœurs CPU"
  type        = number
  default     = null
}

variable "memory" {
  description = "La mémoire allouée à la VM (en Mo)"
  type        = number
  default     = null
}

variable "disk_size" {
  description = "La taille du disque de la VM (en Go)"
  type        = string
  default     = null
}

variable "storage" {
  description = "Le stockage où placer le disque"
  type        = string
  default     = null
}

variable "iso_path" {
  description = "Le chemin de l'image ISO pour la VM"
  type        = string
  default     = null
}

variable "network_model" {
  description = "Le modèle réseau pour la VM"
  type        = string
  default     = null
}

variable "bridge" {
  description = "Le pont réseau utilisé par la VM"
  type        = string
  default     = null
}

Ce fichier contient les valeurs des variables pour personnaliser la configuration Terraform :

hcl

vm_name       = "MyNewVM"
target_node   = "node-01"
template_name = "rocky-linux-template"
cores         = 4
memory        = 4096
disk_size     = "30G"
storage       = "local"
iso_path      = "local:iso/Rocky-8.10-x86_64-minimal.iso"
network_model = "virtio"
bridge        = "vmbr0"

Nous allons utiliser ici les informations du token que nous avons créé précédemment.

bash

export PM_API_TOKEN_ID='terraform@pve!terraform'
export PM_API_TOKEN_SECRET="aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
Persistance
Ajoutez ces commandes à votre fichier ~/.bashrc pour les rendre permanentes.

Ce fichier contient la logique pour créer une VM à partir d’un template ou d’une image ISO.

hcl

resource "proxmox_vm_qemu" "vmdeployed" {

  name        = var.vm_name
  target_node = var.target_node
  clone       = var.template_name
  cores       = var.cores
  memory      = var.memory

  disks {
    virtio {
      virtio0 {
        disk {
          size = var.disk_size
          storage = var.storage
        }
      }
    }
  }

  network {
    id = 1
    model = var.network_model
    bridge = var.bridge
  }

}

hcl

resource "proxmox_vm_qemu" "vmdeployed" {

  name        = var.vm_name
  target_node = var.target_node
  cores       = var.cores
  memory      = var.memory

  disks {
    virtio {
      virtio0 {
        disk {
          size = var.disk_size
          storage = var.storage
        }
      }
    }
    ide {
      ide0 {
        cdrom {
          iso = var.iso_path
        }
      }
    }
  }

  network {
    id = 1
    model = var.network_model
    bridge = var.bridge
  }

}

Avant de déployer votre infrastructure, initialisez votre projet Terraform pour télécharger les plugins nécessaires :

bash

terraform init -upgrade

Cette commande télécharge et installe les plugins nécessaires, comme le provider Proxmox spécifié dans notre fichier providers.tf. Elle configure également le répertoire de travail pour gérer le fichier d’état (state) de Terraform.

Avant de lancer la création de la VM, vérifiez que votre configuration est correcte avec la commande suivante :

bash

terraform validate

Cela vous permet de détecter d’éventuelles erreurs dans vos fichiers de configuration.

Générez un plan d’exécution pour voir ce que Terraform va faire :

bash

terraform plan

Cette commande génère un aperçu des actions que Terraform va effectuer pour atteindre l’état désiré. Elle affiche les ressources à ajouter, modifier ou supprimer.

Info
Aucun changement réel n’est effectué à ce stade.

Si tout est correct, appliquez le plan pour créer la VM :

bash

terraform apply

Terraform vous demande de confirmer les actions avant de les appliquer. Tapez yes pour procéder.

Attention
Il est également possible d’utiliser la commande suivante pour confirmer automatiquement et éviter d’avoir à le faire manuellement. Cependant, cette option doit être utilisée avec parcimonie : terraform apply -auto-approve

Si vous souhaitez supprimer la VM et les ressources associées, utilisez la commande suivante :

bash

terraform destroy

Vous avez maintenant déployé une machine virtuelle sur Proxmox avec Terraform, en utilisant soit un template, soit une image ISO de Rocky Linux. Grâce à l’approche Infrastructure as Code, votre déploiement est automatisé, reproductible et facilement versionné.

Dans un prochain tutoriel (disponible ici) , nous verrons comment intégrer Ansible pour personnaliser et configurer vos VMs, en installant des services comme Apache, Nginx, et bien plus encore.