Aller au contenu principal

L'inventaire Dynamique Ansible pour Proxmox

En tant que spécialiste DevOps, j'ai exploré en profondeur les capacités individuelles de Proxmox, Terraform et Ansible. Cependant, la véritable magie opère lorsque l'on intègre ces technologies ensemble. Ce guide de blog vise à plonger dans cette synergie, en mettant l'accent sur l'utilisation de Terraform pour le provisionnement et d'Ansible pour la configuration fine des machines virtuelles (VMs) dans un environnement Proxmox.

Prérequis et Contexte

Avant de plonger dans les détails techniques de l'intégration de Terraform et Ansible pour la gestion des VMs dans Proxmox, il est important de comprendre le contexte et les prérequis nécessaires à cette mise en œuvre. Mon expérience m'a montré que la réussite de tout projet d'infrastructure as code (IaC) repose sur une fondation solide et une compréhension claire des objectifs.

Contexte

Nous sommes dans un environnement où Proxmox est déjà en place, servant de plateforme pour la virtualisation de serveurs. Proxmox offre une flexibilité remarquable dans la gestion des ressources de virtualisation et se présente comme une solution idéale pour des environnements cloud privés ou hybrides.

Terraform, dans ce cadre, est envisagé comme l'outil de provisionnement. Sa capacité à décrire l'infrastructure de manière déclarative permet une approche systématique et reproductible. En définissant l'infrastructure sous forme de code, Terraform facilite sa création, modification et duplication.

Ansible, d'autre part, est choisi pour la configuration post-provisionnement des VMs. Sa nature agentless et son approche par modules le rendent adapté pour une large gamme de tâches de configuration et d'automatisation.

Prérequis

Pour mettre en œuvre cette intégration, certains éléments sont essentiels :

  • Connaissance de Base : Des connaissances basiques de Proxmox, Terraform et Ansible nécessaire. Bien que je ne m'étende pas sur les bases de ces outils, leur manipulation requiert une certaine familiarité.
  • Accès et Permissions : Un accès approprié au cluster Proxmox, ainsi que les permissions requises pour créer et gérer des VMs.

Vous cochez toutes les cases ? Oui, alors passons à la suite.

Avantages de l'Intégration Terraform et Ansible

L'association de Terraform pour le provisionnement et d'Ansible pour la configuration représente une stratégie puissante dans la gestion d'infrastructures, en particulier pour les clusters Proxmox. Cette combinaison apporte plusieurs avantages significatifs :

L'un des principaux atouts de cette intégration est l'automatisation du cycle de vie complet des VMs. Terraform gère efficacement le déploiement initial et la gestion des ressources de votre infrastructure. Ensuite, Ansible prend le relais pour effectuer des tâches de configuration détaillées et complexes. Ce flux de travail continu garantit que l'ensemble du processus, de la création à la configuration, est automatisé, réduisant ainsi les risques d'erreurs manuelles.

La description déclarative de Terraform assure que les ressources sont déployées de manière cohérente à chaque fois. Cette uniformité est cruciale pour éviter les "drifts" d'infrastructure. De son côté, Ansible, avec ses playbooks, garantit que chaque VM est configurée selon des standards établis. Cela est particulièrement bénéfique dans les environnements où la conformité et la standardisation sont critiques.

Terraform excelle dans la gestion de l'état de l'infrastructure, permettant des mises à jour prévisibles et des changements contrôlés. Cette fonctionnalité est essentielle pour maintenir l'intégrité de l'infrastructure sur le long terme. Ansible, grâce à son principe d'idempotence, ne modifie les configurations que si le résultat souhaité n'est pas déjà atteint, assurant ainsi une gestion efficace des configurations sans répétitions inutiles.

Cette approche permet une gestion facile et efficace de clusters de grande taille. Avec Terraform, l'ajout ou la suppression de VMs peut être effectué rapidement et de manière contrôlée. Ansible, avec sa capacité à gérer simultanément plusieurs hôtes, rend la configuration à grande échelle gérable et systématique.

En conclusion, l'intégration de Terraform et Ansible pour la gestion de VMs dans Proxmox offre une solution robuste, automatisée et évolutive pour les administrateurs systèmes. Cela permet une meilleure allocation des ressources, une diminution des coûts opérationnels et une plus grande flexibilité dans la gestion des infrastructures cloud privées.

Mise en Pratique

La mise en œuvre pratique de notre stratégie d'infrastructure as code (IaC) nécessite une intégration fluide entre Terraform pour le provisionnement et Ansible pour la configuration, avec un accent particulier sur l'utilisation de l'inventaire dynamique Ansible pour Proxmox.

Provisionnement avec Terraform

Terraform dans notre workflow est de provisionner et de gérer l'état des VMs dans Proxmox. Cette partie a été expliquée dans le guide précédent.

Nous avons donc une machine nommée test.robert.local provisionné dans notre Proxmox.

Configuration avec Ansible

Une fois que Terraform a provisionné les VMs, Ansible entre en jeu pour leur configuration. Vous pouvez utiliser Ansible pour automatiser des tâches telles que la mise à jour des systèmes ou l'installation de logiciels.

Mais voilà comment récupérer automatiquement un inventaire provenant de Proxmox. C'est là qu'entre en jeu, l'inventaire dynamique Ansible.

Mise en place de l'inventaire dynamique Ansible pour Proxmox

Pour cela, vous devez d'abord installer la collection community.general si ce n'est pas déjà fait :

ansible-galaxy collection install community.general

Ensuite, configurez votre inventaire Ansible pour utiliser le plugin Proxmox de cette collection. Voici un exemple de configuration d'inventaire dans un fichier se terminant par .proxmox.yml or .proxmox.yaml :

plugin: community.general.proxmox
url: https://proxmox2.robert.local:8006
user: 'terraform-prov@pve'
token_id: 'terraform'
token_secret: '85b12793-73c5-4d72-87b8-xxxxxxxx'

Ce fichier permet à Ansible de se connecter à Proxmox et de récupérer automatiquement la liste des VMs pour la configuration.

Testons tout de suite :


ansible-inventory -i test.proxmox.yml --graph

@all:
  |--@ungrouped:
  |--@proxmox_all_lxc:
  |--@proxmox_all_qemu:
  |  |--test.robert.local
  |--@proxmox_all_running:
  |  |--test.robert.local
  |--@proxmox_all_stopped:
  |--@proxmox_nodes:
  |  |--devbox1
  |--@proxmox_devbox1_lxc:
  |--@proxmox_devbox1_qemu:
  |  |--test.robert.local

Yes !!!!

Ajoutons quelques lignes à notre fichier d'inventaire, pour recupérer les adresse IP des VMs et les classer en utilisant les tags :

want_proxmox_nodes_ansible_host: true
compose:
  ansible_host: proxmox_agent_interfaces[1]["ip-addresses"][0].split('/')[0]
keyed_groups:
  - key: proxmox_tags_parsed
    separator: ""
groups:
  ubuntu_servers: "'ubuntu' in (proxmox_tags_parsed|list)"

On relance :


ansible-inventory -i test.proxmox.yml --list

{
    "_meta": {
        "hostvars": {
            "devbox1": {
                "ansible_host": null
            },
            "test.robert.local": {
                "ansible_host": "192.168.3.167",
                "proxmox_agent": {
                    "enabled": "1",
                    "fstrim_cloned_disks": "0",
                    "type": "virtio"
                },
                "proxmox_agent_interfaces": [
                    {
                        "ip-addresses": [
                            "127.0.0.1/8",
                            "::1/128"
                        ],
                        "mac-address": "00:00:00:00:00:00",
                        "name": "lo"
                    },
                    {
                        "ip-addresses": [
                            "192.168.3.167/24",
                            "fe80::be24:11ff:fe14:d15c/64"
                        ],
                        "mac-address": "bc:24:11:14:d1:5c",
                        "name": "eth0"
                    }
                ],
                "proxmox_balloon": 0,
                "proxmox_boot": "c",
                "proxmox_bootdisk": "scsi0",
                "proxmox_cicustom": {
                    "meta": "local:snippets/test.robert.local-ci-meta_data.yml",
                    "user": "local:snippets/test.robert.local-ci-user.yml"
                },
                "proxmox_cores": 1,
                "proxmox_cpu": {
                    "cputype": "x86-64-v2-AES"
                },
                "proxmox_cpuunits": 1024,
                "proxmox_digest": "2548e52c60fd0746c90df542edd81bc9ff541f97",
                "proxmox_ide2": {
                    "disk_image": "local:100/vm-100-cloudinit.qcow2",
                    "media": "cdrom"
                },
                "proxmox_ipconfig0": {
                    "ip": "dhcp"
                },
                "proxmox_memory": "2048",
                "proxmox_meta": {
                    "creation-qemu": "8.1.2",
                    "ctime": "1703606559"
                },
                "proxmox_name": "test.robert.local",
                "proxmox_net0": {
                    "bridge": "vmbr0",
                    "firewall": "0",
                    "virtio": "BC:24:11:14:D1:5C"
                },
                "proxmox_node": "devbox1",
                "proxmox_numa": 0,
                "proxmox_onboot": 1,
                "proxmox_qmpstatus": "running",
                "proxmox_scsi0": {
                    "disk_image": "local:100/vm-100-disk-0.raw",
                    "size": "10G"
                },
                "proxmox_scsihw": {
                    "disk_image": "virtio-scsi-single"
                },
                "proxmox_serial0": "socket",
                "proxmox_smbios1": {
                    "uuid": "d8a217d0-5928-455d-884a-3a13cc2af1c9"
                },
                "proxmox_snapshots": [],
                "proxmox_sockets": 1,
                "proxmox_status": "running",
                "proxmox_tags": "ubuntu",
                "proxmox_tags_parsed": [
                    "ubuntu"
                ],
                "proxmox_vga": "serial0",
                "proxmox_vmgenid": "893ee004-af33-43f6-9134-ff833ec58598",
                "proxmox_vmid": 100,
                "proxmox_vmtype": "qemu"
            }
        }
    },
    "all": {
        "children": [
            "ungrouped",
            "proxmox_all_lxc",
            "proxmox_all_qemu",
            "proxmox_all_running",
            "proxmox_all_stopped",
            "proxmox_nodes",
            "proxmox_devbox1_lxc",
            "proxmox_devbox1_qemu",
            "ubuntu_servers",
            "ubuntu"
        ]
    },
    "proxmox_all_qemu": {
        "hosts": [
            "test.robert.local"
        ]
    },
    "proxmox_all_running": {
        "hosts": [
            "test.robert.local"
        ]
    },
    "proxmox_devbox1_qemu": {
        "hosts": [
            "test.robert.local"
        ]
    },
    "proxmox_nodes": {
        "hosts": [
            "devbox1"
        ]
    },
    "ubuntu": {
        "hosts": [
            "test.robert.local"
        ]
    },
    "ubuntu_servers": {
        "hosts": [
            "test.robert.local"
        ]
    }
}

Pour simplifier les commandes, nous allons créer un fichier ansible.cfg avec ce contenu :

[defaults]
inventory = ./inventory.proxmox.yml
host_key_checking = False
forks = 10
roles_path = ./roles

[ssh_connection]
pipelining = True

On récupère pas mal de facts. Lors du provisionnement avec Terraform on pourrait imaginer ajouter des customs facts Ansible.

Configuration des VMs avec Ansible

Avec l'inventaire dynamique configuré, Ansible peut maintenant joindre les VMs de Proxmox et appliquer les configurations nécessaires. Cela peut inclure la mise à jour des systèmes, la configuration des réseaux, l'installation de logiciels et plus encore. L'avantage de cet inventaire dynamique est qu'il reflète en temps réel l'état du cluster Proxmox, permettant ainsi à Ansible de cibler précisément les VMs nécessitant une configuration ou une mise à jour.

Un exemple

Je vous propose un playbook ansible visant à configurer cette machine avec des petits rôles, sans aucune prétention, que je mets à disposition sur Ansible Galaxy. Il ne fonctionne qu'avec des VM tournant sous Ubuntu 22.04 !

Commençons par les installer. Créez un fichier ansible-requirements.yml et déposez-y ceci :

---
roles:
  - name: stephrobert.bootstrap
    version: 1.0.4
  - name: stephrobert.motd
    version: 1.0.1

Passons à l'écriture du playbook, en mettant les machines du groupe ubuntu_servers comme machine cible :

---
- name: Test ansible
  hosts: ubuntu
  gather_facts: true

  pre_tasks:
    - name: Install Local-All
      ansible.builtin.package:
        name:
          - locales-all
        state: present
      become: true
    - name: Set Hostname
      ansible.builtin.hostname:
        name: test.robert.local
      become: true
  roles:
    - role: stephrobert.bootstrap
    - role: stephrobert.motd

Lançons le playbook :

bob@internal ~/Projects/perso/terraform-proxmox ❯ ansible-playbook playbook.yml

PLAY [Test ansible] *****

TASK [Gathering Facts] *****
ok: [test.robert.local]

TASK [Install Local-All] *****
ok: [test.robert.local]

TASK [Set Hostname] *****
ok: [test.robert.local]

PLAY RECAP *****
test.robert.local          : ok=14   changed=1    unreachable=0    failed=0    skipped=5    rescued=0    ignored=0

Vérifions notre VM

On se connecte à la machine test.robert.local avec son adresse IP. Par la suite, je vais réinstaller PowerDns dans mon Homelab pour récupérer automatiquement les IP des machines.

ssh 192.168.1.167
Warning: Permanently added '192.168.3.167' (ED25519) to the list of known hosts.
     _             _               _               _
 ___| |_ ___ _ __ | |__  _ __ ___ | |__   ___ _ __| |_
/ __| __/ _ \ '_ \| '_ \| '__/ _ \| '_ \ / _ \ '__| __|
\__ \ ||  __/ |_) | | | | | | (_) | |_) |  __/ |  | |_
|___/\__\___| .__/|_| |_|_|  \___/|_.__/ \___|_|   \__|
            |_|
System info:
  Hostname····: test.robert.local
  Distro······: Ubuntu 20.04.6 LTS
  Kernel······: Linux 5.4.0-169-generic
  Uptime······: up 1 hour, 3 minutes
  Load········: 0.00 (1m), 0.02 (5m), 0.00 (15m)
  Processes···: 103 (root), 8 (user), 111 (total)
  CPU·········: QEMU Virtual CPU version 2.5+ (1 vCPU)
  Memory······: 138Mi used, 1.6Gi avail, 1.9Gi total

Disk usage:
  /                              26% used out of  11G
  [=============·····································]
  /boot/efi                       6% used out of 110M
  [===···············································]

Last login: Wed Dec 27 10:36:17 2023 from 192.168.3.1

Cool !

Conclusion

L'utilisation conjointe de Terraform pour le provisionnement et de l'inventaire dynamique Ansible pour la configuration des VMs crée un processus d'infrastructure as code (IaC) fluide et automatisé. Cette méthode garantit non seulement une gestion efficace des VMs dans Proxmox mais assure également que l'environnement reste dynamique, adaptable et conforme aux besoins évolutifs de l'infrastructure.

En résumé, cette approche intégrée de Terraform et de l'inventaire dynamique Ansible, en particulier celui de la collection community.general, représente une stratégie efficace pour une gestion optimisée des VMs dans un environnement cloud privé Proxmox.

Dans un prochain guide, j'aborderai les modules de cette collection permettant de provisionner toutes sortes de ressources Proxmox.