Retour aux articles

Le Cloud sur votre PC - Partie 3 : Automatiser la configuration de machines avec Ansible

· 10 min read

Dans la première partie, nous avons créé des VM avec Multipass, préparé des accès SSH et fait communiquer nos machines. Dans la deuxième, nous avons confié leur création à Terraform : nos serveurs sont maintenant décrits dans des fichiers.

Pour 1 ou 2 VMs, faire SSH et y installer des outils, c'est plutot facile. Mais quand il s'agit d'une dizaine de VMs, cela le devient moins. Il faut donc un outil capable d'aller sur les VMs, installer les dépendences dont nous avons, et nous faire un rapport.

C'est la suite de notre labo : utiliser Ansible pour configurer nos VMs.

Attention

L’objectif est simplement de voir comment utiliser Ansible pour configurer nos VM, en abordant les points essentiels. L’apprentissage complet d’Ansible dépasse le cadre de cet article.

Les prérequis

Pour suivre cet article, prévoyez :

  • La partie 1 et 2 ;
  • quelques notions de base en Linux et SSH ;
  • Docker fonctionnel, avec Compose et Buildx, pour suivre l’exemple proposé (optionnel);
  • Nne connexion Internet pour télécharger les outils et les paquets ;
  • Les fichiers du labo, disponibles dans le dossier infra/multipass-terraform-ansible du dépôt the-labs.

Ansible, c'est quoi ?

Ansible est un outil d’automatisation et de gestion de configuration informatique. Il permet d’exécuter automatiquement des tâches sur plusieurs machines, comme : installer des paquets, gérer des fichiers, préparer des utilisateurs ou démarrer des services.

Fonctionnement de Ansible

Ansible se connecte généralement aux machines distantes, notamment aux VMs Linux, via SSH, puis exécute des actions à l’aide de modules spécialisés.

Les actions Ansible peuvent être organisées de différentes manières :

  • Les commandes Ad-hoc : commandes Ansible exécutées directement, sans utiliser de Playbook. Elles sont utiles pour effectuer rapidement une tâche ponctuelle.
  • Les Modules : petites unités de code permettant d’effectuer une action précise, comme installer un paquet, créer un fichier, gérer un utilisateur ou démarrer un service.
  • Les Playbooks : fichiers écrits en YAML qui décrivent une suite de tâches à exécuter sur une ou plusieurs machines.
  • Les Roles : structures permettant d’organiser, de réutiliser et de maintenir plus facilement les tâches, variables, fichiers, templates et autres éléments d’une configuration Ansible.

Et cloud-init alors ?

Souvenez-vous : dans la première partie, notre cloud-config préparait la machine au démarrage. Nous allons conserver cette approche pour installer le strict nécessaire à son accès.

Ansible prendra ensuite le relais pour appliquer et faire évoluer la configuration sur les VMs déjà disponibles. Dans notre parcours :

  • Multipass fournit les machines ;
  • Terraform pilote leur création à partir des fichiers .tf ;
  • cloud-init prépare l'accès initial ;
  • Ansible exécute nos tâches de configuration après leur création.

Les possibilités des outils se recoupent, mais ce partage des rôles nous permet d'avancer sans tout mélanger.

Que se passe-t-il en vrai ?

Ansible lit un inventaire (un annuaire qui liste les machines à cibler, leur adresse et leurs utilisateurs de connexion et les accès.) pour connaître les machines cibles et leurs informations de connexion. Il lit ensuite les tâches du Playbook, les exécute sur les VMs et retourne les résultats.

Ansible expliqué

Dans notre cas :

  • Conteneur : nœud de contrôle où Ansible est installé.
  • VMs : machines gérées.
  • Pas d’agent Ansible permanent sur les VMs : Ansible utilise notamment SSH pour communiquer avec elles.
À retenir

Ansible pour ses opérations sur les VMs cibles, à besoin d'un utilisateur disposant d'un accès root (recommandé); de Python installé sur les cibles ; et surtout, l'utilsateur doit avoir les accès SSH configurés !

Pour explorer Ansible plus largement, la documentation officielle sera votre point de départ. Ici, restons sur notre première configuration à deux machines.

Installer Ansible

Pour travailler avec Ansible, vous avez juste besoin de l'installer sur un PC (qui devient le maître, le controlleur, le donneur d'ordre). Mais personnellement, je prefère l'utiliser depuis un conteneur docker.

bash
sudo apt install ansible
# ou
python -m pip install ansible

Mais j'ai ma péférence pour l'utilisation d'un conteneur docker.

Pourquoi je construis mon image Ansible

Personnellement, je préfère garder Ansible et ses dépendances Python dans une image construite pour le projet. Je sais ce que j'y installe et je sépare cet environnement des paquets déjà présents sur mon PC.

La bonne pratique que je retiens est de décrire aussi l'environnement de mon outil d'automatisation. Le Dockerfile peut être versionné avec les playbooks, et l'image partagée. Le conteneur n'est pas obligatoire, mais c'est l'approche que nous suivrons ici.

Les fichiers sont dans the-labs/infra/multipass-terraform-ansible. Depuis le dossier Terraform précédent :

bash
cd multipass-terraform-ansible

Nous utiliserons son Dockerfile, docker-bake.hcl, compose.yml et le sous-dossier ansible/.

Pour créer l'image

bash
docker buildx bake -f docker-bake.hcl --load ansible

Le compose permet de lancer le conteneur, ensuite, il ne reste plus qu'a exécuter les commandes depuis sont l'intérieur.

bash
# lancer
docker compose up ansible -d

# executer une commande
docker compose exec ansible sh -c "ansible --version"

Continuer notre labo

Les fichiers de configuration pour créer vos VMs avec Terraform sont disponible dans le dossier infra/multipass-terraform-ansible.

Il nous faut aussi Docker fonctionnel en mode conteneurs Linux, avec Compose et Buildx, et la paire de clés SSH utilisée pour le labo en partie 1. Il est tout à fait possible d'installer directement ansible sur votre PC et de l'utiliser pour ce lab.

Préparer l'accès qui manque

Dans les parties précédentes, nous avions configuré les clés SSH dans nos VM. Ces clés nous permettaient d’établir des connexions SSH. Nous allons exploiter ces accès SSH dans cette partie.

Dans votre copie locale de infra/multipass-terraform, adaptez config/srv-01.yml et config/srv-02.yml. Pour cette initiation, ils peuvent tous deux contenir cette préparation minimale :

yaml
#cloud-config
package_update: true
packages:
  - zsh

users:
  - default
  - name: demo
    shell: /bin/bash
    lock_passwd: true
    sudo: "ALL=(ALL) NOPASSWD:ALL"
    ssh_authorized_keys:
      - "REMPLACEZ_PAR_VOTRE_CLE_PUBLIQUE"

runcmd:
  - systemctl enable ssh
  - systemctl start ssh

Remplacez la valeur par le contenu complet de votre fichier .pub, pas par un chemin et surtout pas par la clé privée. Nous utiliserons l'utilisateur demo pour notre automatisation.

Bon à savoir

Les droits sudo sans mot de passe simplifient ce labo, et donnent à demo un accès administrateur complet. Il est recommandé d'avoir un utilisateur dédié pour les opérations avec ansible dans vos configuration. exple : automation, ansible, etc.

Donner au conteneur les fichiers et les accès

Le service ansible de compose.yml utilise notre image. Il monte le dossier local ansible/ dans /ansible : vous modifiez les playbooks sur votre PC, ils sont disponibles dans le conteneur sans reconstruire l'image.

La clé privée est fournie au démarrage, jamais intégrée au Dockerfile. Le Compose cherche par défaut ${HOME}/.ssh/automation_key. Adaptez configs.private_key.file pour désigner la clé privée qui correspond à la clé publique installée plus haut : si vous aviez choisi local_key dans la partie 1, c'est ce fichier qu'il faut utiliser, pas en générer un autre.

Attention

Ne commitez pas votre clé.

Nous allons reconnaître nos serveurs avant de lancer les tâches. Démarrez le conteneur et ouvrez son shell :

bash
docker compose up -d ansible
docker compose exec ansible sh

Puis, dans le conteneur :

bash
ansible --version
pwd

Vous devez retrouver Ansible et le dossier /ansible. Voilà, nous avons préparé les machines d'un côté et leur outil de configuration de l'autre.

L'inventaire : retrouver nos deux VM

Sur votre PC, ouvrez ansible/inventory/hosts.yml.

yaml
all:
  vars:
    ansible_user: demo
    ansible_ssh_private_key_file: /root/.ssh/private_key
  children:
    all_servers:
      hosts:
        srv-01:
          ansible_host: srv-01.multipass
        srv-02:
          ansible_host: srv-02.multipass

Le groupe all_servers contient nos deux machines. ansible_host indique où les joindre, ansible_user avec quel utilisateur, et le chemin de clé désigne le fichier dans le conteneur.

Souvenez-vous du réseau de la partie 1 : identifier une VM et résoudre son nom sont deux choses différentes. Ici, le conteneur possède lui aussi son environnement réseau. Les noms .multipass ou .mshome.net ne sont utilisables que s'ils se résolvent depuis celui-ci. Nous commençons donc par les IP.

Depuis le shell du conteneur, essayez SSH :

bash
ssh -i /root/.ssh/private_key demo@srv-01.multipass

Comparez l'empreinte proposée avec celle obtenue sur le PC via Multipass :

bash
multipass exec srv-01 -- uname

Après vérification, acceptez-la, puis utilisez exit pour revenir au conteneur. Répétez pour srv-02. Les empreintes restent dans le known_hosts de ce conteneur ; prévoyez de les conserver ou de les vérifier de nouveau si vous le recréez.

Si SSH échoue déjà par IP, vérifiez le routage et les pare-feu entre Docker et Multipass avant de continuer. Ansible utilisera ce même chemin réseau.

Niveau 1 : Une première commande

Les commandes Ansible suivantes sont à lancer dans le conteneur, depuis /ansible :

bash
ansible all_servers -i inventory/hosts.yml -m ansible.builtin.ping

Ansible ping les VMs

all_servers sélectionne notre groupe, -i indique l'inventaire et -m le module à exécuter. Vous attendez pong pour les deux VM.

Attention, ce n'est pas le ping réseau de la première partie : Ansible vérifie ici la connexion et l'exécution d'un petit module Python sur chaque cible.

Essayons une commande ponctuelle :

bash
ansible all_servers -i inventory/hosts.yml -m ansible.builtin.command -a "uptime"

-a transmet les arguments au module. Vous obtenez un résultat pour chaque machine, sans ouvrir vous-même deux sessions SSH. C'est ce qu'on appelle une commande ad hoc.

Niveau 2 : Conserver nos tâches dans un playbook

Un Playbook Ansible est un fichier, généralement écrit en YAML, qui décrit les tâches qu’Ansible doit exécuter sur un ou plusieurs serveurs.

Pour aller au-delà d'une commande ponctuelle, reprenons ansible/playbooks/demo.yml. Le dépôt montre l'installation de btop et la gestion du service SSH.

Dans votre copie locale, utilisez cette version simplifiée : elle cible all_servers plutôt que le groupe prod absent de notre inventaire, et écarte le handler mal orthographié du brouillon.

yaml
- name: Préparer nos serveurs de développement
  hosts: all_servers
  become: true

  tasks:
    - name: Installer btop
      ansible.builtin.apt:
        name: btop
        state: present
        update_cache: true
        cache_valid_time: 3600

    - name: Vérifier que le service SSH est démarré
      ansible.builtin.service:
        name: ssh
        state: started
        enabled: true

hosts choisit les machines et tasks décrit les opérations. become: true utilise ici sudo : c'est pour cela que nous avons préparé les droits de demo avant de commencer.

state: present demande que btop soit installé. state: started demande que SSH fonctionne ; enabled: true prépare son démarrage automatique.

Vérifiez puis exécutez, depuis le conteneur :

bash
ansible-playbook -i inventory/hosts.yml playbooks/demo.yml --syntax-check
ansible-playbook -i inventory/hosts.yml playbooks/demo.yml

Lancement du playbook demo

La vérification de syntaxe ne teste pas les connexions ; la seconde commande applique les tâches. Avec un compte qui demande un mot de passe sudo, ajoutez --ask-become-pass.

Dans le récapitulatif, ok compte les tâches réussies, changed celles qui ont modifié quelque chose, unreachable les machines injoignables et failed les échecs. Vérifiez le résultat :

bash
ansible all_servers -i inventory/hosts.yml -m ansible.builtin.command -a "btop --version"

Félicitations ! Nous avons fait évoluer les deux serveurs sans les recréer avec Terraform.

Conclusion

Avec Ansible, nous avons atteint une nouvelle étape dans l’automatisation de notre lab. Nous pouvons maintenant appliquer une même configuration à plusieurs machines sans avoir à intervenir manuellement sur chacune d’elles.

Ce lab reste volontairement simple, mais il pose les bases de pratiques que nous retrouverons dans des environnements plus importants : automatisation, reproductibilité et gestion de configuration. Nous savons créer les machines, les atteindre et les configurer, sans confondre ces trois opérations. Notre labo commence à prendre forme, n'est-ce pas ?

Il ne reste plus qu’à aller plus loin avec Ansible et découvrir comment structurer des configurations plus complexes et réutilisables.

Victor Agbalenyo

Écrit par

Victor Agbalenyo

Ingénieur fullstack, architecte DevSecOps et ingénieur en énergies renouvelables. J'écris sur le cloud, la sécurité et l'énergie.