# deploy-vm Rôle Ansible pour déployer des VMs Proxmox depuis un template cloud-init. Supporte le déploiement multi-VM, la migration inter-nœuds, le redimensionnement de disque et l'ajout de disques supplémentaires. ## Fonctionnement 1. **asserts** — valide les variables obligatoires et les formats (IP CIDR, taille disque, extra disks) 2. **clone** — détecte le nœud du template dans le cluster, vérifie si la VM existe déjà, clone si non (idempotent) 3. **migrate** — si `proxmox_node` est différent du nœud du template, migre la VM hors-ligne vers le nœud cible 4. **configure** — applique CPU, RAM, sockets, cloud-init (IP/gateway/DNS/SSH), démarrage auto, resize disque et ajout de disques supplémentaires 5. **start** — démarre la VM et affiche un résumé ## Prérequis - Ansible >= 2.14 - Collection `community.general >= 9.0.0` : ```bash ansible-galaxy collection install -r requirements.yml ``` - Template Proxmox cloud-init existant (Packer ou manuel) - Accès API Proxmox (utilisateur + mot de passe) ## Variables ### Obligatoires par VM (dans la liste `vms`) | Champ | Description | Exemple | |----------|----------------------------------|----------------------| | `name` | Nom de la VM dans Proxmox | `"srv-web01"` | | `ip` | Adresse IP en notation CIDR | `"192.168.1.100/24"` | ### Connexion Proxmox (à stocker dans vault) | Variable | Description | |------------------------|------------------------------------| | `proxmox_api_user` | Utilisateur Proxmox (`user@realm`) | | `proxmox_api_password` | Mot de passe Proxmox | ### Infrastructure (globales) | Variable | Description | Défaut | |--------------------------|-----------------------------------------------------------------------------|---------| | `proxmox_host` | Adresse de l'API Proxmox | `""` | | `proxmox_storage` | Pool de stockage par défaut pour le clone | `""` | | `proxmox_node` | Nœud cible pour la VM. Vide = même nœud que le template. Surchargeble par VM. | `""` | | `proxmox_validate_certs` | Valider le certificat TLS de l'API | `false` | | `template_name` | Nom du template source (surchargeble par VM) | `""` | ### Ressources VM (globales, surchargeables par VM) | Variable | Description | Défaut | |---------------|----------------------|--------| | `vm_cores` | Nombre de vCPUs | `2` | | `vm_sockets` | Nombre de sockets | `1` | | `vm_memory` | RAM en Mo | `2048` | ### Réseau (globales, surchargeables par VM) | Variable | Description | Défaut | |--------------|--------------------------------|--------------------------------------| | `vm_gateway` | Passerelle par défaut | `"192.168.1.1"` | | `vm_dns` | Liste des serveurs DNS | `["9.9.9.9", "8.8.8.8", "8.8.4.4"]` | ### Disque principal (globales, surchargeables par VM) | Variable | Description | Défaut | |----------------|-----------------------------------------------------------------------------|----------| | `vm_disk_name` | Identifiant du disque à redimensionner | `"scsi0"` | | `vm_disk_size` | Taille cible. Vide = pas de resize. Format : `"50G"`, `"500M"`, `"+10G"` | `""` | > **Note** : `vm_disk_size` avec préfixe `+` agrandit le disque existant. Sans préfixe, définit la taille absolue. Proxmox **ne réduit pas** les disques. ### Disques supplémentaires (surchargeables par VM) | Variable | Description | Défaut | |-----------------|---------------------------------------------------------------|--------| | `vm_extra_disks`| Liste de disques supplémentaires à créer | `[]` | Champs de chaque disque : | Champ | Obligatoire | Description | Exemple | |-------------|:-----------:|-------------------------------------------------|---------------| | `disk` | ✓ | Slot Proxmox (`scsi1`, `virtio1`, `sata1`…) | `"scsi1"` | | `size` | ✓ | Taille absolue (pas de `+`). Format : `NUNité` | `"50G"` | | `storage` | | Pool de stockage (défaut : `proxmox_storage`) | `"datavm"` | | `ssd` | | Émuler un SSD | `true` | | `iothread` | | Activer iothread | `true` | | `backup` | | Inclure dans les sauvegardes | `true` | | `cache` | | Mode de cache (`writeback`, `none`…) | `"writeback"` | ### Cloud-init (globales, surchargeables par VM) | Variable | Description | Défaut | |-----------------|------------------------------------------------------|--------| | `vm_ciuser` | Utilisateur créé par cloud-init | `""` | | `vm_cipassword` | Mot de passe (préférer `vm_sshkeys`, stocker en vault) | `""` | | `vm_sshkeys` | Clés SSH publiques (séparées par `\n`) | `""` | ### Options de déploiement (globales, surchargeables par VM) | Variable | Description | Défaut | |-------------------------------|------------------------------------------------------------------|---------| | `vm_full_clone` | Clone complet (`true`) ou lié (`false`) | `true` | | `vm_start_on_boot` | Démarrage automatique avec le nœud Proxmox | `true` | | `vm_wait_timeout` | Timeout pour le clone et le démarrage (secondes) | `300` | | `vm_force_update` | Autoriser la reconfiguration d'une VM existante | `false` | | `vm_migrate_with_local_disks` | Migrer les disques locaux (nécessaire si stockage non partagé) | `true` | ## Utilisation ### 1. Installer les dépendances ```bash ansible-galaxy collection install -r requirements.yml ``` ### 2. Déclarer les VMs dans les variables du play ```yaml # group_vars/proxmox.yml (ou host_vars, ou directement dans le playbook) proxmox_host: "192.168.1.4" proxmox_storage: "datavm" proxmox_node: "proxmox01" # nœud par défaut pour toutes les VMs template_name: "template-debian-12" vms: - name: srv-web01 ip: "192.168.1.101/24" cores: 2 memory: 2048 disk_size: "30G" - name: srv-db01 ip: "192.168.1.110/24" cores: 4 memory: 8192 disk_size: "50G" extra_disks: - disk: scsi1 size: "100G" storage: "datavm" ssd: true backup: true - name: srv-app01 ip: "192.168.1.120/24" proxmox_node: "proxmox02" # nœud différent → migration automatique cores: 4 memory: 4096 disk_size: "30G" ``` ### 3. Appeler le rôle dans un playbook ```yaml - hosts: proxmox gather_facts: false vars_files: - vault.yml roles: - role: brainsys.deploy_vm tags: deploy_vm ``` ### 4. Lancer le déploiement ```bash ansible-playbook playbooks/proxmox.yml \ -l proxmox01.homelab.example.com \ -t deploy_vm \ --ask-vault-pass ``` ### 5. Reconfigurer une VM existante Par défaut le rôle échoue si la VM existe déjà (protection contre les modifications accidentelles). Pour autoriser la reconfiguration : ```bash ansible-playbook playbooks/proxmox.yml \ -l proxmox01.homelab.example.com \ -t deploy_vm \ --ask-vault-pass \ -e vm_force_update=true ``` Ou par VM dans la liste : ```yaml vms: - name: srv-web01 ip: "192.168.1.101/24" force_update: true ``` ## Champs disponibles dans la liste `vms` Chaque item de la liste `vms` peut surcharger n'importe quelle variable globale : | Champ | Variable rôle correspondante | |-----------------------------|-----------------------------------| | `name` | `vm_name` *(obligatoire)* | | `ip` | `vm_ip` *(obligatoire)* | | `id` | `vm_id` (auto si absent) | | `proxmox_node` | `proxmox_node` | | `template_name` | `template_name` | | `cores` | `vm_cores` | | `sockets` | `vm_sockets` | | `memory` | `vm_memory` | | `gateway` | `vm_gateway` | | `dns` | `vm_dns` | | `disk_name` | `vm_disk_name` | | `disk_size` | `vm_disk_size` | | `extra_disks` | `vm_extra_disks` | | `ciuser` | `vm_ciuser` | | `cipassword` | `vm_cipassword` | | `sshkeys` | `vm_sshkeys` | | `full_clone` | `vm_full_clone` | | `start_on_boot` | `vm_start_on_boot` | | `wait_timeout` | `vm_wait_timeout` | | `force_update` | `vm_force_update` | | `migrate_with_local_disks` | `vm_migrate_with_local_disks` | ## Sécurité - Chiffrer `vault.yml` avec `ansible-vault encrypt vault.yml` — ne jamais le committer en clair. - Préférer les clés SSH (`vm_sshkeys`) aux mots de passe cloud-init (`vm_cipassword`). - Créer un utilisateur Proxmox dédié avec les permissions minimales plutôt que d'utiliser `root@pam`. - Ajouter `vault.yml` au `.gitignore` si le fichier n'est pas chiffré. ## Licence MIT