Dans le chapitre précédent, vous avez fait connaissance avec Ansible, vous avez préparé votre architecture pour déployer MediaWiki sur 2 serveurs à l’aide d’un node manager, vous avez installé les outils Ansible sur le node manager et regardé d’un peu plus près les 3 outils Ansible dont vous allez avoir besoin par la suite.
Dans ce chapitre, vous allez préparer la communication avec les nodes. C’est-à-dire que vous allez installer les prérequis pour que le node manager puisse communiquer avec les nodes et leur envoyer les commandes Ansible.
Préparez la communication
Vous allez donc déployer automatiquement MediaWiki sur les 2 nodes, en utilisant Ansible et les scripts d’automatisation depuis le node manager.
Ansible travaille avec des outils déjà très utilisés sur les systèmes Linux. En effet, Ansible a uniquement besoin de SSH et de Python pour fonctionner. Il faut donc au minimum que ces 2 outils soient installés et fonctionnels sur le node manager et les nodes.
Pour établir la communication et avoir le droit de lancer des commandes à distance, vous avez besoin de :
Définir un inventaire des nodes.
Vérifier la connexion SSH entre le node manager et les nodes.
Lancer un ping avec Ansible sur les nodes.
Vérifier que Python est installé sur les nodes.
Créer un simple utilisateur sur les nodes.
Attribuer les droits sudo à cet utilisateur.
Créer une paire de clés SSH pour cet utilisateur.
Copier la clé publique SSH sur les nodes.
Définissez un inventaire des nodes
Il est temps de baptiser vos serveurs :
sur le serveur 1 seront installés Apache, PHP et MediaWiki ; nous l'appellerons donc http1 ;
sur le serveur 2 sera installé MariaDB ; nous l'appellerons donc bdd1.
Comme vous n’avez pas accès au DNS de l’entreprise, vous décidez de configurer la résolution de nom via le fichier /etc/hosts sur le node manager.
Dans l’absolu, il faut utiliser les noms de machine plutôt que les adresses IP. Les noms des nodes sont toujours à enregistrer dans un DNS. Pour l'exercice qui se concentre sur la pratique de Ansible, vous prenez un raccourci en utilisant le fichier /etc/hosts. Ce fichier permet de mettre en place des correspondances entre les noms des serveurs et leurs adresses IP.
Connectez-vous sur le node manager en root :
root@node-manager:~#
Ajoutez dans le fichier /etc/hosts sur le node manager l’enregistrement des 2 nodes :
127.0.0.1 localhost 127.0.1.1 node-manager # le node http1 192.168.122.11 http1 # le node bdd1 192.168.122.12 bdd1
Cette action vous permettra d’utiliser les noms http1 et bdd1 pour communiquer avec les nodes.
Créez le fichier inventaire Ansible
À ce stade, vous allez commencer à utiliser les commandes Ansible pour faire la suite des actions.
Pour fonctionner, Ansible a besoin d’un fichier inventaire. Ce fichier contient la liste des nodes. Vous allez donc enregistrer le nom des nodes dans ce fichier.
Placez-vous dans votre environnement virtuel :
root@node-manager:~# su - user-ansible user-ansible@node-manager:~$ source ansible/bin/activate
Puis éditez avec la commande vi le fichier inventaire.ini :
(ansible) user-ansible@node-manager:~$ vi inventaire.ini
Mettez dans ce fichier les 2 noms des nodes :
http1 bdd1
Vi n’est pas obligatoire ; si vous êtes plus à l’aise avec un autre éditeur, utilisez-le !
Le fichier inventaire est au format INI par défaut, il suit donc la syntaxe de ce format. Ansible sait travailler avec d’autres formats de données, il suffit d’activer les bons plugins. Vous trouverez la liste des plugins d'inventaire ici.
Vérifiez que vous communiquez avec les nodes
Avant d’utiliser Ansible pour commencer à automatiser des tâches, lancez une connexion SSH sur les nodes pour enregistrer la fingerprint (l'empreinte du serveur qui doit être vérifiée pour être sûr de se connecter au bon node) sur le node manager. Il faut le faire au moins une fois, sinon Ansible râlera à la première connexion, car le paquet sshpass ne sait pas gérer le fingerprint.
user-ansible@node-manager:~$ ssh root@http1 root@http1's password: Linux node-www 5.10.0-11-amd64 #1 SMP Debian 5.10.92-1 (2022-01-18) x86_64 The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Last login: Mon Feb 14 12:07:26 2022
Répondez yes et faites la même chose pour bdd1.
Utilisez la commande ansible en mode ad-hoc
Vous allez commencer à utiliser Ansible (en mode ad-hoc, c'est-à-dire avec des commandes manuelles plutôt que des scripts) pour mettre en place les prérequis. Ceci vous permettra de les automatiser et de les appliquer à tous les nodes en même temps.
Les commandes ad-hoc sont des actions rapides qui ne nécessitent pas forcément de les sauvegarder pour plus tard. Vous pouvez vous référer à la documentation d'Ansible sur les commandes ad-hoc pour approfondir.
Lancez maintenant un ping avec Ansible dans votre environnement de travail virtuel :
(ansible) user-ansible@node-manager:~$ ansible -i inventaire.ini -m ping http1 --user root --ask-pass SSH password: http1 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "changed": false, "ping": "pong" }
Vous venez d’utiliser la commande ansible avec plusieurs options :
-i : indique à Ansible l’emplacement du fichier inventaire ;
-m : indique à Ansible d’utiliser le module ping ;
http1 : indique à Ansible de faire l’action sur le node http1 ;
--user : indique à Ansible d’utiliser l’utilisateur root pour se connecter au node (pas le choix pour le moment, car c’est le seul compte dont vous disposez) ;
--ask-pass : indique à Ansible de demander le mot de passe SSH ;
http1 : indique à Ansible de lancer la commande sur le node http1.
Le retour de la commande vous indique que l’action est un succès et répond pong au ping ! Le node http1 est bien joignable.
Ansible ne lance pas la commande ping, il lance un module qui fait la même chose que la commande ping.
Un module est un programme utilisé pour exécuter une tâche ou une commande Ansible. Chaque tâche utilise un module et un seul, qui peut prendre des arguments pour être exécuté de manière personnalisée. Ansible fournit de nombreux modules, mais vous pouvez créer le vôtre, personnalisé.
Tous les modules officiels d’Ansible sont téléchargés sur votre poste lors de l’installation d’Ansible. Lorsque vous utilisez un module, Ansible ira chercher le code à exécuter dans le dossier du module sur votre poste. Si vous avez installé Ansible dans un environnement virtuel avec pip, les modules se trouvent à l’adresse ./ansible/lib/python2XY/site-packages/ansible
.
La syntaxe et les options de la commande ansible sont disponibles sur la documentation d'Ansible.
Vérifiez que Python est installé sur les nodes
Il arrive parfois que Python ne soit pas installé sur le node ; dans ce cas, vous pouvez utiliser un module spécial : raw, qui permet de passer des commandes Ansible sans utiliser Python :
(ansible) user-ansible@node-manager:~$ ansible -i inventaire.ini -m raw -a "apt install -y python3" http1 --user root --ask-pass SSH password: http1 | CHANGED | rc=0 >> Lecture des listes de paquets... Fait Construction de l'arbre des dépendances... Fait Lecture des informations d'état... Fait python3 est déjà la version la plus récente (3.9.2-3). 0 mis à jour, 0 nouvellement installés, 0 à enlever et 0 non mis à jour. Shared connection to http1 closed.
Vous avez utilisé l’option -m pour appeler le module raw avec l’argument “apt install -y python3”, qui a pour effet d’installer Python en version 3 sur le node http1.
En réalité, les modules Ansible peuvent être écrits avec un autre langage que Python. Le module raw, écrit en Shell, en est la preuve ! Un atout supplémentaire en faveur d'Ansible.
Créez l’utilisateur user-ansible sur les nodes
Vous allez suivre les bonnes pratiques en créant un simple utilisateur pour ne pas travailler directement avec le compte root.
Mais avant de créer un utilisateur, vous allez générer un mot de passe chiffré (au format reconnu par Linux) avec Ansible :
(ansible) user-ansible@node-manager:~$ ansible localhost -i inventaire.ini -m debug -a "msg={{'passforce'|password_hash('sha512','secretsalt')}}" localhost | SUCCESS => { "msg": "$6$secretsalt$X5YDmUgDphPxnMkByvHbNaiP4T5Uk0WjEZ9TukWKQnXmXN81jG3DcGZnNJiSz9ltgPhplH92HOR/RqgmyS.zN1" }
Dans cette commande, nous avons utilisé le module debug avec l’argument msg pour transformer le mot de passe "passforce" en une chaîne chiffrée avec l’algorithme sha512. “Secretsalt” est ce qu’on appelle le sel. C’est un mot qui permet de renforcer la sécurité de l’algorithme en apportant une inconnue en plus dans le processus de cryptage du mot de passe.
L'option "localhost" a permis d’indiquer à Ansible de lancer la commande sur localhost (en local sur le node manager).
Vous allez maintenant pouvoir créer l’utilisateur user-ansible avec un mot de passe chiffré, grâce à la commande suivante :
(ansible) user-ansible@node-manager:~$ ansible -i inventaire.ini -m user -a 'name=user-ansible password=$6$secretsalt$X5YDmUgDphPxnMkByvHbNaiP4T5Uk0WjEZ9TukWKQnXmXN81jG3DcGZnNJiSz9ltgPhplH92HOR/RqgmyS.zN1' --user root --ask-pass all SSH password: http1 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "changed": true, "comment": "", "create_home": true, "group": 1001, "home": "/home/user-ansible", "name": "user-ansible", "password": "NOT_LOGGING_PASSWORD", "shell": "/bin/sh", "state": "present", "system": false, "uid": 1001 } bdd1 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "changed": true, "comment": "", "create_home": true, "group": 1001, "home": "/home/user-ansible", "name": "user-ansible", "password": "NOT_LOGGING_PASSWORD", "shell": "/bin/sh", "state": "present", "system": false, "uid": 1001 }
Vous avez utilisé le module user avec les arguments name et password, et vous avez demandé à Ansible de lancer la commande sur all (sur tous les nodes présents dans le fichier inventaire).
Donnez les droits sudo à user-ansible
Connectez-vous au node http1, installez le package sudo (apt get install sudo), et regardez le fichier /etc/sudoers ; il contient les configurations de sudo :
Vous pouvez voir la ligne suivante :
## Allows people in group sudo to run all commands %sudo ALL=(ALL) ALL
Le groupe sudo a les droits sudo. Vous allez donc ajouter l’utilisateur user-ansible dans le groupe sudo sur tous les nodes :
(ansible) user-ansible@node-manager:~$ ansible -i inventaire.ini -m user -a 'name=user-ansible groups=sudo append=yes ' --user root --ask-pass all SSH password: http1 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "append": true, "changed": true, "comment": "", "group": 1001, "groups": "sudo", "home": "/home/user-ansible", "move_home": false, "name": "user-ansible", "shell": "/bin/sh", "state": "present", "uid": 1001 } bdd1 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "append": true, "changed": true, "comment": "", "group": 1001, "groups": "sudo", "home": "/home/user-ansible", "move_home": false, "name": "user-ansible", "shell": "/bin/sh", "state": "present", "uid": 1001 }
Un moyen de vérifier que user-ansible a bien les droits sudo est de relancer la commande précédente, mais en ajoutant de nouvelles options :
(ansible) user-ansible@node-manager:~$ ansible -i inventaire.ini -m user -a 'name=user-ansible groups=sudo append=yes ' --user user-ansible --ask-pass --become --ask-become-pass all SSH password: BECOME password[defaults to SSH password]: bdd1 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "append": true, "changed": false, "comment": "", "group": 1001, "groups": "sudo", "home": "/home/user-ansible", "move_home": false, "name": "user-ansible", "shell": "/bin/sh", "state": "present", "uid": 1001 } http1 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "append": true, "changed": false, "comment": "", "group": 1001, "groups": "sudo", "home": "/home/user-ansible", "move_home": false, "name": "user-ansible", "shell": "/bin/sh", "state": "present", "uid": 1001 }
La commande s’est bien passée, car le retour est un SUCCESS ! Vous avez les privilèges sudo.
Ici, vous avez utilisé le module user pour ajouter user-ansible dans le groupe wheel et vous avez utilisé deux nouvelles options :
--become : Ansible vous permet de "devenir" un autre utilisateur en utilisant sudo ;
--ask-become-pass : Ansible demande le mot de passe sudo (qui est le même que le mot de passe de user-ansible).
Dorénavant, nous n’utiliserons plus root, mais l’utilisateur user-ansible en mode sudo pour passer les commandes Ansible.
Créez les clés SSH
Pour se connecter en SSH, il est recommandé d’utiliser une paire de clés plutôt que d’utiliser un mot de passe.
La communication SSH est établie sur la base de clés SSH ; cette pratique est conseillée, car elle permet un niveau d’authentification beaucoup plus sûr que l’authentification par mot de passe.
Vous allez maintenant créer une paire de clés SSH de type ecdsa pour l’utilisateur user-ansible.
Commencez par vous remettre en utilisateur user-ansible avec la commande suivante si c'est nécessaire :
# su - user-ansible user-ansible@node-manager:~$
Et lancez la création des clés avec la commande suivante :
user-ansible@node-manager:~$ ssh-keygen -t ecdsa Generating public/private key pair. Enter file in which to save the key (/home/user-ansible/.ssh/id_ecdsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/user-ansible/.ssh/id_ecdsa Your public key has been saved in /home/user-ansible/.ssh/id_ecdsa.pub The key fingerprint is: SHA256:dJfRsev7RlWVLd4e9aUCBOdX+SqdkwaH0f9tGruLYLU user-ansible@node-manager They key's randomart image is: +---[ECDSA 256]---+ | .oo .ooo=| | o. .+=o=| | . o.++.*=| | . . o+ +o*| | S .=.==| | ..oO *| | o Eo.B | | . . .o..| | . +=.| The key fingerprint is: SHA256:geBOUCBR+4ljdMOn5QVmq9R7dpgmwYsAv995BtTWCYg user-ansible@node-manager The key's randomart image is: +---[ECDSA 256]---+ |+o+oo.+.. | | + =E*.= o . | | = B X = o | | . X @ * + | | = B * S . | | . o . B . | | . o o | | o | | | +----[SHA256]-----+
Vous pouvez laisser tout par défaut, sans rien changer. Il n’est pas nécessaire de mettre de passphrase.
Ajoutez la clé publique de l’utilisateur user-ansible sur les nodes
Vous allez utiliser le module authorized_key pour enregistrer la clé publique de l'utilisateur user-ansible sur tous les nodes. Ainsi, vous pourrez vous connecter aux nodes sans saisir de mot de passe SSH.
(ansible) user-ansible@node-manager:~$ ansible -i inventaire.ini -m authorized_key -a 'user=user-ansible state=present key="{{ lookup("file", "/home/user-ansible/.ssh/id_ecdsa.pub") }}"' --user user-ansible --ask-pass --become --ask-become-pass all SSH password: BECOME password[defaults to SSH password] http1 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "changed": true, "comment": null, "exclusive": false, "follow": false, "key": "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBAOS9i3B7TxpPkV8a2S8DLeVX5HWYaGTl435CDy+PmKGMOCi3PnvZQ6GmaXyht+EhQUQSM0dUJ9wQC8wjwM0xes= user-ansible@node-manager", "key_options": null, "keyfile": "/home/user-ansible/.ssh/authorized_keys", "manage_dir": true, "path": null, "state": "present", "user": "user-ansible", "validate_certs": true } bdd1 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "changed": true, "comment": null, "exclusive": false, "follow": false, "key": "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBAOS9i3B7TxpPkV8a2S8DLeVX5HWYaGTl435CDy+PmKGMOCi3PnvZQ6GmaXyht+EhQUQSM0dUJ9wQC8wjwM0xes= user-ansible@node-manager", "key_options": null, "keyfile": "/home/user-ansible/.ssh/authorized_keys", "manage_dir": true, "path": null, "state": present, "user": "user-ansible", "validate_certs": true }
Vous avez utilisé de nouvelles options :
-m authorized_key : module authorized_key (ajoute ou supprime les clés SSH pour des utilisateurs) ;
user=user-ansible : l’utilisateur concerné est user-ansible ;
state=present : indique d’ajouter le fichier ;
key="{{ lookup("file", "/home/user-ansible/.ssh/id_ecdsa.pub") }}" : utilise la commande lookup pour rechercher le fichier concerné.
Relancez la commande mais cette fois sans --ask-pass (demande le mot de pass SSH) :
(ansible) user-ansible@node-manager:~$ ansible -i inventaire.ini -m authorized_key -a 'user=user-ansible state=present key="{{lookup("file", "/home/user-ansible/.ssh/id_ecdsa.pub") }}"' --user user-ansible --become --ask-become-pass all BECOME password: http1 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "changed": false, "comment": null, "exclusive": false, "follow": false, "key": "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBAOS9i3B7TxpPkV8a2S8DLeVX5HWYaGTl435CDy+PmKGMOCi3PnvZQ6GmaXyht+EhQUQSM0dUJ9wQC8wjwM0xes= user-ansible@node-manager", "key_options": null, "keyfile": "/home/user-ansible/.ssh/authorized_keys", "manage_dir": true, "path": null, "state": "prensent, "user": "user-ansible", "validate_certs": true, } bdd1 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "changed": false, "comment": null, "exclusive": false, "follow": false, "key": "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBAOS9i3B7TxpPkV8a2S8DLeVX5HWYaGTl435CDy+PmKGMOCi3PnvZQ6GmaXyht+EhQUQSM0dUJ9wQC8wjwM0xes= user-ansible@node-manager", "key_options": null, "keyfile": "/home/user-ansible/.ssh/authorized_keys", "manage_dir": true, "path": null, "state": "prensent, "user": "user-ansible", "validate_certs": true,
Un seul mot de passe vous a été demandé, celui de sudo uniquement.
Voilà, vous pouvez exécuter avec Ansible des commandes distantes sur les nodes avec le privilège sudo. À vous l’automatisation sans limite !
Résumé
Dans ce chapitre, vous avez préparé la communication avec les nodes ; vous avez notamment :
créé un fichier inventaire et ajouté les nodes dans ce fichier ;
utilisé la commande ansible en mode ad-hoc pour vérifier la présence de Python sur les nodes et lancer un ping ;
créé un utilisateur user-ansible sur les nodes ;
créé des clés SSH pour l'utilisateur user-ansible ;
donné les privilèges sudo à user-ansible pour pouvoir exécuter des commandes en tant que super utilisateur sur les nodes ;
enregistré la clé publique de user-ansible sur les nodes pour sécuriser les communications.
Dans le prochain chapitre, vous allez dérouler le déploiement d'une application avec Ansible.