Aller au contenu

🚀 Déploiement IaC : Proxmox + Terraform + Ansible

Objectif : Automatiser le cycle de vie d'une machine virtuelle (VM). 1. Provisioning : Déploiement de la VM sur Proxmox via Terraform. 2. Configuration : Installation et paramétrage d'un serveur Web Nginx via Ansible.


📋 Prérequis

  • Un cluster ou un nœud Proxmox VE 8+.
  • Un template Cloud-Init existant (ID 9000 dans cet exemple).
  • Une machine de contrôle (Linux/WSL) avec terraform et ansible installés.

1. Préparation Proxmox (Côté Serveur)

Avant d'initier le code, un accès programmatique sécurisé doit être configuré sur l'hyperviseur.

1.1 Création de l'utilisateur

  1. Aller dans Datacenter > Permissions > Users > Add.
  2. Remplir les champs :
    • User : terraform
    • Realm : Proxmox VE authentication server (pve)
      > ⚠️ Attention : Ne pas sélectionner PAM.
    • Password : [Définir un mot de passe robuste]

1.2 Attribution des permissions

  1. Aller dans Datacenter > Permissions > Add > User Permission.
  2. Configuration :
    • Path : /
    • User : terraform@pve
    • Role : Administrator (ou PVEAdmin pour plus de restrictions, mais Administrator est recommandé pour le lab).

1.3 Génération du Token API

  1. Aller dans Datacenter > Permissions > API Tokens > Add.
  2. Configuration :
    • User : terraform@pve
    • Token ID : tf-token
    • Privilege Separation :DÉCOCHER (Impératif pour hériter des droits admin).
  3. Secret : Copier l'UUID immédiatement. > ⚠️ Important : Ce secret ne sera affiché qu'une seule fois. Sauvegardez-le sécurisé.

2. Terraform (Le Provisioning)

Terraform est utilisé pour déclarer l'état souhaité de l'infrastructure. Nous utilisons le provider moderne bpg/proxmox.

📂 Structure du projet

Text Only
~/proxmox-lab/
├── main.tf          # Définition des ressources (VM)
├── provider.tf      # Configuration du plugin Proxmox (bpg)
├── variables.tf     # Déclaration des variables
└── terraform.tfvars # Secrets (Exclus du Git via .gitignore)

📄 Fichiers de configuration

provider.tf

Configuration du connecteur API vers Proxmox.

Terraform
terraform {
  required_providers {
    proxmox = {
      source  = "bpg/proxmox"
      version = "0.60.0"
    }
  }
}

provider "proxmox" {
  endpoint = var.proxmox_api_url

  # Syntaxe bpg : USER@REALM!TOKENID=SECRET
  api_token = "${var.proxmox_api_token_id}=${var.proxmox_api_token_secret}"

  # Ignorer la validation SSL pour les environnements de Lab (Self-signed)
  insecure = true

  ssh {
    agent = true
  }
}

main.tf

Définition de la VM.

Terraform
resource "proxmox_virtual_environment_vm" "web_server" {
  name      = "vm-terraform-01"
  node_name = "proxAMD" # ⚠️ Doit correspondre exactement au nom du nœud
  vm_id     = 500

  clone {
    vm_id = 9000  # ID du Template Cloud-Init source
    full  = true
  }

  agent {
    enabled = true
  }

  # Option critique : évite que Terraform n'attende indéfiniment l'agent au premier boot
  started = true

  cpu {
    cores = 2
    type  = "host"
  }

  memory {
    dedicated = 2048
  }

  network_device {
    bridge = "vmbr0"
  }

  initialization {
    ip_config {
      ipv4 {
        address = "192.168.1.50/24"
        gateway = "192.168.1.1"
      }
    }

    user_account {
      username = "ubuntu"
      keys     = [var.ssh_public_key]
    }
  }
}

💻 Commandes de déploiement

Bash
# Initialiser le répertoire et télécharger le provider
terraform init

# Vérifier le plan d'exécution
terraform plan

# Appliquer la configuration (Création de la VM)
terraform apply -auto-approve

3. Ansible (La Configuration)

Une fois la VM en ligne, Ansible prend le relais pour configurer le système d'exploitation et les services.

⚙️ Installation (Machine de contrôle)

Bash
sudo apt update && sudo apt install -y ansible

📄 Fichiers de configuration

inventory.ini

L'inventaire définit les cibles.

INI
[webservers]
192.168.1.50 ansible_user=ubuntu ansible_ssh_common_args='-o StrictHostKeyChecking=no'
# Note : La clé SSH est gérée par l'agent SSH local ou spécifiée via ansible_ssh_private_key_file

playbook.yml

La "recette" d'installation.

YAML
---
- name: Configurer le Serveur Web Nginx
  hosts: webservers
  become: true  # Élévation de privilèges (sudo)

  tasks:
    - name: Mettre à jour le cache APT
      apt:
        update_cache: yes
        cache_valid_time: 3600

    - name: Installer les paquets requis
      apt:
        pkg:
          - nginx
          - qemu-guest-agent
        state: present

    - name: Activer et démarrer les services
      service:
        name: "{{ item }}"
        state: started
        enabled: yes
      loop:
        - nginx
        - qemu-guest-agent

    - name: Déployer la page d'accueil personnalisée
      copy:
        dest: /var/www/html/index.html
        mode: '0644'
        content: |
          <!DOCTYPE html>
          <html>
          <head>
              <meta charset="UTF-8">
              <title>Proxmox Lab</title>
          </head>
          <body>
              <h1>Succès ! 🚀</h1>
              <p>Infrastructure déployée par Terraform, configurée par Ansible.</p>
          </body>
          </html>

🚀 Exécution du Playbook

Bash
ansible-playbook -i inventory.ini playbook.yml

4. ✅ Vérification et Dépannage

Vérification

  1. Ouvrez votre navigateur.
  2. Accédez à http://192.168.1.50.
  3. Vous devriez voir le message : "Succès ! 🚀".

🔧 Guide de dépannage (Retex)

Erreur / Symptôme Cause probable Solution
Error: No such cluster node Le node_name dans main.tf est incorrect ou c'est une IP. Utiliser le nom d'hôte exact du nœud Proxmox (ex: proxAMD).
Terraform bloqué sur "Creating..." Terraform attend que le qemu-guest-agent remonte l'IP, mais il n'est pas installé sur le template. S'assurer que started = true est présent dans main.tf pour ne pas bloquer le processus, puis installer l'agent via Ansible.
Panic Error / Crash Utilisation du provider obsolète telmate/proxmox. Migrer impérativement vers bpg/proxmox pour Proxmox 8+.
Problèmes d'encodage (é) Manque de charset dans le HTML généré. Toujours inclure <meta charset="UTF-8"> dans le template HTML Ansible.

ℹ️ Note : Pour détruire l'environnement et repartir de zéro, utilisez la commande terraform destroy.