Déployer une VM Proxmox avec Terraform et Ansible

Dans un précédent tutoriel, nous avons vu comment déployer une machine virtuelle (VM) sur Proxmox en utilisant Terraform. Ce guide complète ce processus en ajoutant une personnalisation de la VM grâce à Ansible.

  • Terraform : Un outil d’Infrastructure as Code (IaC) qui permet de définir et déployer des infrastructures de manière reproductible.
  • Ansible : Un outil d’automatisation qui facilite la configuration et la gestion des systèmes.
  • Déployer une VM sur Proxmox avec Terraform.
  • Configurer et personnaliser la VM avec Ansible.
  • Appliquer les bonnes pratiques pour sécuriser vos secrets.

Avant de commencer, assurez-vous d’avoir les éléments suivants :

  1. Un template sur Proxmox
    Vous devez avoir un template configuré avec une adresse IP attribuée dynamiquement par DHCP. Pour créer un template, consultez ce tutoriel.

  2. Un token d’authentification Proxmox
    Par souci de sécurité, utilisez un token API au lieu d’un utilisateur et d’un mot de passe. Pour savoir comment créer un token avec les permissions minimales nécessaires, consultez ce tutoriel.

  3. Terraform, Ansible et Packer installés
    Assurez-vous d’avoir installé les outils suivants sur votre machine :

    • Terraform pour l’automatisation de l’infrastructure.
    • Ansible pour la configuration et la personnalisation de la VM.
    • Packer (facultatif, mais recommandé pour créer vos propres templates).
  4. Un accès SSH à la VM
    Votre template doit être configuré avec un utilisateur SSH et un mot de passe (ou une clé SSH) pour permettre la connexion.


Protéger vos secrets (mots de passe, tokens, etc.) est essentiel pour éviter des fuites accidentelles. Voici quelques bonnes pratiques :

  • Utilisez des variables d’environnement : Cela empêche les secrets d’apparaître dans vos fichiers de configuration.
  • Stockez vos secrets dans un gestionnaire de secrets comme HashiCorp Vault.
  • Ne versionnez jamais de fichiers contenant des secrets dans un dépôt Git, comme terraform.tfvars.
  • Ajoutez un fichier .gitignore pour exclure les fichiers sensibles.

Voici la structure de base de notre projet Terraform :

plaintext

.
├── providers.tf
├── variables.tf
├── main.tf
├── terraform.tfvars
├── ansible
│   └── playbook.yml

Ce fichier configure le provider Proxmox pour Terraform. Nous utilisons ici le provider Telmate/Proxmox.

hcl

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

provider "proxmox" {
  pm_api_url      = "https://votre-serveur-proxmox:8006/api2/json"
  pm_api_token_id = "votre-token-id"
  pm_api_token_secret = "votre-token-secret"
  pm_tls_insecure = true
}
Note sur la version
Par défaut, la version 2.9.14 peut être instable selon votre version de Proxmox. Je vous recommande d’utiliser la version 3.0.1-rc6, qui offre une meilleure compatibilité et stabilité.

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
}

variable "target_node" {
  description = "Le nœud Proxmox où déployer la VM"
  type        = string
}

variable "template_name" {
  description = "Le nom du template à utiliser"
  type        = string
}

variable "cores" {
  description = "Nombre de cœurs CPU"
  type        = number
}

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

variable "disk_size" {
  description = "Taille du disque (en Go)"
  type        = string
}

variable "storage" {
  description = "Stockage pour le disque"
  type        = string
}

variable "network_model" {
  description = "Modèle réseau"
  type        = string
}

variable "bridge" {
  description = "Pont réseau"
  type        = string
}

variable "ansible_user" {
  description = "Utilisateur pour la connexion Ansible"
  type        = string
  sensitive   = true
}

variable "ansible_password" {
  description = "Mot de passe pour la connexion Ansible"
  type        = string
  sensitive   = true
}

Ce fichier définit les actions suivantes :

  • Création de la VM sur Proxmox : La ressource Terraform utilise un template configuré en DHCP.
  • Récupération dynamique de l’adresse IP : Une ressource supplémentaire get_vm_ip permet de récupérer l’adresse IP pour Ansible.
  • Génération automatique du fichier inventory : L’adresse IP récupérée par la ressource get_vm_ip est inscrite dans le fichier inventory.ini, qui sera ensuite consommé utilisé par Ansible.
  • Exécution d’Ansible : Terraform déclenche ensuite l’exécution du playbook Ansible pour personnaliser la VM.

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
  agent       = 1
  skip_ipv6   = true

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

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

resource "null_resource" "get_vm_ip" {
  depends_on = [proxmox_vm_qemu.vmdeployed]

  provisioner "local-exec" {
    command = <<EOT
      echo "[all]" > inventory.ini
      echo "${proxmox_vm_qemu.vmdeployed.ssh_host} ansible_user=${var.ansible_user} ansible_password=${var.ansible_password}" >> inventory.ini
    EOT
  }
}

resource "null_resource" "run_ansible" {
  depends_on = [null_resource.get_vm_ip]

  provisioner "local-exec" {
    command = <<EOT
      ssh-keyscan -t rsa ${proxmox_vm_qemu.vmdeployed.ssh_host} >> ~/.ssh/known_hosts
      ansible-playbook -i inventory.ini ansible/playbook.yml
    EOT
  }
}

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

hcl

vm_name       = "MyNewVM"
target_node   = "pve1"
template_name = "rocky-linux-template"
cores         = 4
memory        = 4096
disk_size     = "30G"
storage       = "local"
network_model = "virtio"
bridge        = "vmbr1"
ansible_user     = "root"
ansible_password = "password"

Dans cet exemple, nous utilisons un playbook très basique pour installer vim sur la VM. Bien sûr, vous pouvez le remplacer ou l’étendre en utilisant des rôles personnalisés ou des collections disponibles sur Ansible Galaxy.

Ce fichier configure Ansible pour personnaliser la VM. Ici, il installe simplement l’éditeur vim :

yaml

- name: Configurer la VM
  hosts: all
  become: yes
  tasks:
    - name: Installer Vim
      yum:
        name: vim
        state: present

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 automatisé le déploiement et la personnalisation d’une VM sur Proxmox avec Terraform et Ansible. Ce processus peut être étendu avec des rôles Ansible personnalisés ou des collections disponibles sur Ansible Galaxy.