Apprendre et Maitriser Ansible l'outil de gestion de configuration
Publié le : 25 septembre 2019 | Mis à jour le : 8 avril 2023Table des matières
Introduction
Dans un monde où les technologies évoluent continuellement à un rythme rapide, les administrateurs système voient leurs responsabilités augmenter. En effet, ils doivent désormais fournir aux développeurs des environnements de développement, de qualification et de pré-production à l’image de ceux de production (DevOps). Pour garantir cette cohérence, ils peuvent s’appuyer sur des langages d’infrastructure as code (IAC) dont fait partie Ansible.
Présentation d’Ansible
La première version d’Ansible est sorti en 2012 et son créateur s’appelle Michael DeHaan. Initialement appelée AnsibleWorks Inc, la société finançant le développement de l’outil ansible a été acquise en 2015 par RedHat lui-même racheté par IBM en 2018. Bien qu’il existe de nombreux outils (Chef, Puppet) qui font la même chose avec quelques différences, Ansible a réussi à les dépasser tous avec sa simplicité, sa sécurité et, surtout sa courbe d’apprentissage fluide.
Ansible était au départ un outil gestion de configuration. La gestion de configuration est un processus dont l’objectif est de définir un état dans lequel doit se trouver les ressources d’une infrastructure informatique : les serveurs, les réseaux, les utilisateurs/groupes, les logiciels et la sécurité.
Mais Ansible a bien évolué et ses modules permettent de prendre en charge aussi les taches de la boucle Devops, comme le :
L’Intégration Continue : La production et le stockage des artefacts à partir des codes sources de l’application doit être aussi automatisé permettant ainsi de fiabiliser leur mise en production. CI pour Continuous Integration.
Le Provisionnement : Le provisioning est le processus qui permet de créer les ressources d’une Infrastructure Informatique : un serveur, réseau, des utilisateurs, des services… Provisionning
Le déploiement Continu : Le déploiement des applications doit être fait de manière fiable et cohérente à partir des artefacts produit durant la phase de Livraison Continue. CD pour Continuous Deployment
Dans ce billet, nous n’aborderons que Ansible. Ansible fait partie d’un ensemble d’application appelé Ansible Automation Platform qui étend son champ d’action à la gestion de WorkFlows Complexes. AWX est un de ces composants, connu sous le nom de d’Ansible Tower dans sa version commerciale. Si vous voulez plus d’informations sur AWX, vous trouverez en bas de ce billet une belle série de liens.
Comment fonctionne Ansible ?
La grande force d’Ansible est qu’il est facile à mettre en œuvre, car il est agent-less, et ne nécessite qu’une connexion SSH et la présence d’une installation minimale de python pour exécuter les tâches décrites.
Lorsqu’il y a plusieurs machines à gérer, Ansible exécute les opérations en parallèle. Cela permet de gagner un temps considérable. Cependant, les tâches sont effectuées dans un ordre définit par l’utilisateur lors du choix de la stratégie : Par défaut Ansible attendra d’avoir fini une tâche (sur tous les hôtes) pour passer à la suivante.
Ansible et plus particulièrement ses modules sont idempotents. Cela signifie qu’une opération donnera le même résultat qu’on l’exécute une ou plusieurs fois. Par exemple, on va vérifier si un utilisateur existe, si c’est le cas, on ne fera rien, mais si l’utilisateur n’existe pas alors, on viendra le créer.
Composants clés
- Node Manager: ou control node, est le poste depuis lequel tout est exécuté via des connexions, essentiellement en SSH, aux nœuds cibles.
- Playbook: Un playbook Ansible décrit une suite de tâches ou de rôles écrits dans un fichier ou format yaml.
- Rôle: Afin d’éviter d’écrire encore et encore le même code dans les playbooks, Ansible permet d’utiliser des librairies regroupant des fonctionnalités spécifiques. Ces librairies sont appelées des rôles qui peuvent donc être utilisés dans les playbooks.
- Inventory: La description des systèmes cibles gérés par Ansible est
appelé un inventaire. A chaque node de l’inventaire, on peut attribuer des
variables. On distingue deux types d’inventaire :
- l’inventaire statique constitué de fichier(s) plats.
- l’inventaire dynamique fourni par un système centralisé. Exemple L’inventaire AWS EC2.
- Module: Les tâches et les rôles font appel à des modules installés avec Ansible. Je vous invite à consulter leur liste sur le site d’Ansible.
- Template: Comme son nom l’indique, un template est un modèle permettant de générer un fichier cible. Ansible utilise Jinja2, un gestionnaire de modèles écrit pour Python. Les « Templates » Jinja2 permettent de gérer des boucles, des tests logiques, des listes ou des variables.
- Notifier: indique que si une tâche change d’état (et uniquement si la
tâche a engendré un changement),
notify
fait appel au handler associé pour exécuter une autre tâche. - Handler: Tâche qui n’est appelée que dans l’éventualité où un notifier est invoqué
- Tag: Nom défini sur une ou plusieurs tâches qui peuvent être utilisé plus tard pour exécuter exclusivement cette ou ces tâches Ansible.
Comment Installer Ansible ?
Ansible ne peut être installé que sur des ordinateurs fonctionnant sur les systèmes d’exploitation Linux et MacOS. La manière la plus propre pour installer d’Ansible sur le node manager se fait via l’utilisation d’un environnement virtuel python ou dans l’espace utilisateur. En effet, ce moyen permet de choisir précisément la version d’ansible et de python à installer.
Je ne décrie ici que l’installation d’Ansible dans l’espace python de l’utilisateur :
Sur des machines à base de Debian
sudo apt update
sudo apt -y upgrade
sudo apt install -y build-essential libssl-dev libffi-dev python3-dev python3-pip
pip3 install ansible --user
Sur des machines à base de RedHat
sudo yum install epel-release
sudo yum install python3-pip
sudo pip3 install -U pip --upgrade
pip3 install ansible --user
Pour installer une version spécifique :
pip3 install --user ansible==6.5.0
Installation de l’autocompletion bash
Depuis la version 2.9 d’Ansible, il est possible d’avoir de l'autocompletion
bash des commandes ansible. Pour cela, il suffit d’installer le package python
argcomplete
:
sudo pip install argcomplete
sudo activate-global-python-argcomplete
Test après installation d’Ansible
Comment exécuter Ansible ? Il suffit de taper la commande suivante qui va simplement lancer en local (-c local) un shell qui exécutera la commande echo ‘salut B0B’:
ansible all -i "localhost," -c local -m shell -a 'echo Salut B0B'
Ce qui donne à l’écran :
localhost | success | rc=0 >>
salut B0B
Dans le vocabulaire Ansible, le fait d’utiliser le binaire ansible
pour
exécuter une simple tâche est une commande ‘ad hoc’. En effet, nous utiliserons
plus souvent la commande ansible-playbook
qui permet elle d’orchestrer un
ensemble de taches. Un exemple de commande ad hoc : rebooter un ensemble de
machines.
Pour tester vos playbooks Ansible je vous conseille de créer des machines virtuelles en utilisant vagrant.
Comment utiliser Ansible ?
Les principales commandes Ansible
Ansible est livré avec un certain nombre de commandes permettant soit de lancer des actions ou, soit d’obtenir de l’information sur l’environnement d’exécution Ansible :
- ansible : Permet d'exécuter un simple module ansible sur un inventaire. Vu ci-dessus dans le premier test.
- ansible-console : Ouvre une console interactive permettant de lancer plusieurs actions sur un inventaire.
- ansible-config : Affiche l’ensemble des paramètres Ansible.
ansible-config [list|dump|view]
.- list : affiche la liste complète des options d’Ansible à disposition.
- dump : affiche la configuration dans le contexte actuel.
- view : affiche le contenu d’un fichier de configuration Ansible
- ansible-playbook : Exécute un playbook Ansible sur un inventaire. La plus connue.
- ansible-vault : Permet de crypter des données qui ne doivent être divulgué.
- ansible-inventory : Affiche l’ensemble des données d’un inventaire Ansible.
- ansible-galaxy : permet d’installer des roles et des collections Ansible
- ansible-doc : Permet de lister l’ensemble des composants Ansible à disposition sur le nœud d’execution
ansible-doc -l -t [type]
type parmi: become, cache, callback, cliconf, connection,httpapi, inventory, lookup, netconf, shell, vars, module, strategy.
Comment construire un inventaire ansible ?
Ici ne sera abordé que la notion d’inventaire statique ansible.
L’inventaire statique sous Ansible est un fichier au format INI. La déclaration d’un groupe se fait en utilisant le nom du groupe entre crochets. Les machines rattachées à ce groupe sont simplement ajoutées à la suite de la déclaration du groupe (une machine par ligne).
Prenez un exemple avec les éléments suivants que vous pouvez instancier avec vagrant :
- un groupe apache constitué de la machine server1
- un groupe Mysql avec la machine server2
Ci-dessous un fichier d’inventaire correspondant à cette déclaration premier_inventaire.ini :
[apache]
server1
[mysql]
server2
Il faut dans un premier temps créer une clé SSH et diffuser la clé publique sur les machines clientes d’Ansible:
ssh-keygen -t rsa
ssh-copy-id -i ~/.ssh/id_rsa.pub server1
ssh-copy-id -i ~/.ssh/id_rsa.pub server2
Démarrons l’agent SSH qui évitera de rentrer la paraphrase à chaque commande :
ssh-agent bash
ssh-add ~/.ssh/id_rsa
À partir de maintenant, il est possible de lancer des commandes unitaires sur
l’inventaire au moyen de la commande Ansible (nous en verrons d’autres).
ansible -i premier_inventaire.ini -m ping all
server1 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
example | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
Le premier paramètre est l’inventaire d’ansible à utiliser, le second le module
à lancer et le dernier la cible. Ici, on exécute le module ping
sur toutes
(all
) les machines se trouvant dans l’inventaire. Il est possible de se
limiter à un groupe ou à une salle machine. ansible -i inventories/premier_inventaire.ini -m ping apache
On peut associer des arguments aux modules avec l’argument (-a).
ansible localhost -m shell -a "python --version"
localhost | CHANGED | rc=0 >>
Python 3.10.7
La commande a fonctionné avec succès. Cet exemple est assez simple, mais pour des tâches plus évoluées, nous allons faire appel au playbook (livre de recette) d’Ansible.
Comment écrire des playbooks Ansible ?
Pour écrire les playbooks, Ansible s’appuie sur le langage YAML. Je vois déjà les critiques fusées, c’est compliqué fastidieux ! Et bien non si vous utilisez un IDE intégrant une extension Ansible.
Revenons à l’écriture de notre premier playbooks :
---
- name: update web servers
hosts: webservers
become: true
tasks:
- name: ensure apache is at the latest version
ansible.builtin.package:
name: httpd
state: latest
...
Donc dans l’exemple ci-dessus, nous avons un playbook ansible dont :
- dont la description (name) est update web servers
- cible les
hosts
du groupe webservers - demande l’élévation de privilège (become) pour exécuter des tâches les nécessitant.
- lance une tache qui vérifie que la dernière version d’apache est bien installé si ce n’est pas le cas, elle l’installe.
Voici les principales règles de syntaxe des fichiers YAML :
- YAML accepte l’ensemble du jeu de caractères Unicode, à l’exception de certains caractères de contrôle, et peut être codé en UTF-8, UTF-16 et UTF-32 (fortement conseillé).
- L’indentation est faite avec l’utilisation des espaces et non les caractères de tabulation.
- Les commentaires commencent par le signe dièse #, peuvent commencer n’importe où sur une ligne puis continuer jusqu’à la fin de la ligne. Par contre, Si le caractère # apparaît à l’intérieur d’une chaîne, alors ce sont des # littéraux.
- Les membres de la liste sont indiqués par un tiret - avec un membre par ligne. Une liste peut également être spécifiée en plaçant le texte entre crochets […], chaque entrée étant séparée par une virgule.
- Une entrée de tableau associatif est représentée en utilisant l’espace suivi de deux-points clé : valeur avec une entrée par ligne.
- Plusieurs documents dans un même flux sont séparés par trois tirets —.
Les taches font appel aux modules ansible. Tous les principaux modules Ansible sont installés avec Ansible. Mais il est possible d’en ajouter via des collections Ansible.
Pour exécuter ce playbook ansible, il faut utiliser la commande ansible-playbook
.
ansible-playbook -i "localhost," -c local playbook.yml
L’affichage est un peu différent :
PLAY [localhost] **************************************************************
GATHERING FACTS ***************************************************************
ok: [localhost]
TASK: [shell echo ’Salut B0B’] ************************************************
changed: [localhost]
PLAY RECAP ********************************************************************
localhost : ok=2 changed=1 unreachable=0 failed=0
Vous pouvez lister tous les modules ansible installés avec la commande
ansible-doc
:
ansible-doc --list
Vous pouvez retrouver leur documentation sur le site officielle d’Ansible
Comment configurer Ansible ?
Le fichier de configuration par défaut se trouve dans le répertoire
/etc/ansible
. Si vous avez installé Ansible avec pip
ce fichier n’existe
pas, mais pas de souci Ansible dans ce cas utilisera des valeurs par défaut.
Pour vérifier qu’Ansible utilise un éventuel fichier de configuration, vous pouvez utiliser la commande suivante :
ansible [core 2.14.0]
config file = None
configured module search path = ['/home/vagrant/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /home/vagrant/.pyenv/versions/3.10.8/lib/python3.10/site-packages/ansible
ansible collection location = /home/vagrant/.ansible/collections:/usr/share/ansible/collections
executable location = /home/vagrant/.pyenv/versions/3.10.8/bin/ansible
python version = 3.10.8 (main, Oct 20 2022, 07:56:05) [GCC 11.2.0] (/home/vagrant/.pyenv/versions/3.10.8/bin/python3.10)
jinja version = 3.1.2
libyaml = False
Dans mon cas, il n’en utilise pas : config file = None
!
Je vous conseille d’en créer un dans les cas spécifiques, pour surcharger les valeurs par défaut. Placez ce fichier dans le répertoire où se trouvent les playbooks à exécuter.
Ce fichier est écrit au format ini
et comprend différentes sections :
[defaults] [privilege_escalation] [paramiko_connection] [ssh_connection] [accelerate] [selinux] [colors]
La commande ansible-config list
la liste de tous les paramètres et de leur
équivalent à mettre dans le fichier ansible.cfg
:
Par exemple, pour paramétrer la localisation de l’inventaire :
DEFAULT_HOST_LIST:
default: /etc/ansible/hosts
description: Comma separated list of Ansible inventory sources
env:
- name: ANSIBLE_INVENTORY
expand_relative_paths: true
ini:
- key: inventory
section: defaults
name: Inventory Source
type: pathlist
yaml:
key: defaults.inventory
Il faudra ajouter dans la section [defaults] la clé (key) inventory
comme ceci
:
[defaults]
inventory = ./inventory/prod1
La commande view
d’ansible-config d’afficher les valeurs courantes.
La commande dump
d’ansible-config permet de retrouver les valeurs qui ont été modifiés :
ansible-config dump --only-changed
DEFAULT_HOST_LIST(/home/vagrant/.local/ansible.cfg) = ['/home/vagrant/.local/inventory/prod1']
Et la suite…
Ce billet avait pour simple objectif de présenter Ansible et de montrer en quoi il peut vous aider à gérer la configuration de vos serveurs. J’espère que cela vous aura donné envie d’aller plus loin dans la gestion de configurations avec Ansible.
Dans cette introduction sur les bases d'Ansible, j’ai décris Ansible, j’ai évoqué ses points forts et les avantages qu’il peut apporter à l’automatisation et à l’orchestration de votre infrastructure. J’ai défini les termes essentiels utilisés et expliciter la structure des playbooks Ansible.
Poursuivre votre formation Ansible
Sur l’écriture de code Ansible
Si vous voulez continuer votre apprentissage d’ansible, je conseille de lire les billets suivants :
- L’écriture de playbooks Ansible plus évolués permettant de configurer et d’installer une application. Mais nous y arborerons aussi d’autres notions comme les variables Ansible, les boucles et conditions Ansible et les templates Ansible.
- Pour vous assister dans l’écriture de playbooks, je vous conseille d’utiliser l’outil Ansible-Lint et l’extension vscode Ansible
- Pour améliorer la qualité de votre code, je conseille l’outil spotter.
- Pour écrire correctement des playbooks Ansible, il faut le faire avec du TDD (Test-Driven Development) qui consistent à écrire un playbook par itération, en écrivant chaque test avant d’écrire la solution.
- Dans certains cas vous pouvez être obligé de recourir aux modules de commandes
comme
shell
etcommand
. Comment les utiliser correctement ? - Pour éviter de vous répéter sans cesse, il faut développer des rôles. Voyons comment écrire vos propres rôles Ansible
- Pour éviter de subir une attaque, protégez vos secrets avec Ansible Vault
- Pour tester les résultats de vos rôles, vous pouvez utiliser molecule
- Maintenant que vous connaissez un grande partie des concepts important d’Ansible, il est temps de lire mes bonnes pratiques.
- La suite sur les tips avec au menu tous les moyens pour optimiser les temps d’exécution des playbooks
- La sécurité est notre priorité et il ne faut pas l’oublier quand on code avec Ansible. C’est pourquoi je vous propose un environnement de développement ansible intégrant OpenScap.
- Si vous avez besoin de variables dynamiques dans vos inventaires, vous pouvez utiliser des customs facts
- Pour manipuler vos variables, vous avez à votre disposition les filtres Ansible. 1, 2 et 3
- Pour générer des fichiers de configurations, des lignes de commandes, vous pouvez recourir aux templates Jinja.
- Pour vous aider à comprendre le fonctionnement des principaux modules Ansible :
- Ansible est un gestionnaire de configuration, on se doit de gérer ses inventaires. Mais cela demande de comprendre la précédence d’Ansible.
- Parfois les inventaires statiques ne suffisent plus et c’est qu’interviennent les inventaires dynamiques d’ansible
- Pour simplifier le décryptage de la sortie des commandes avec le filtre jc
- Ansible et les taches asynchrones
- Comment distribuer tout ce qui compose un environnement Ansible avec les collections Ansible
- Ansible ne permet pas que de piloter la configuration de machines Linux ! On peut également gérer des machines tournant sous Windows avec Ansible
- Pour répondre à vos questions.
Développer des modules et des plugins à Ansible
- Il se peut, c’est de plus en plus rare, que vous ne trouviez pas de modules
répondant à votre besoin. Alors, plutôt que de recourir au module
shell
, vous pouvez développer vos propres modules Ansible - Pour adapter Ansible à vos besoins, il est possible de développer vos propres plugins de filtres et lookup
Installer et Utiliser Ansible AWX
- Ansible - Premiers pas avec AWX
- Installer Ansible AWX sur un cluster Kubernetes et une variante utilisant une BDD externe
- Les excellents Workflows d’Ansible AWX
- Les environnements d’exécution d’Ansible
- Utiliser la CLI Ansible AWX dans vos pipelines de CI/CD
Quelques outils complémentaires à Ansible
- Ansible-later une alternative à Ansible-Lint
- Ansible playbook Grapher pour créer des graphes de taches et rôles à partir des playbooks.
- Ansible-Navigator une CLI regroupant la plupart des commandes ansible
- Construire une CMDB avec ansible
- Utiliser un poste Windows comme noeud ansible avec cygwin
- Mise à jour des versions dans les playbooks avec Renovate
- Monitorer l’exécution de vos playbooks avec Splunk
- Gérer les événements avec ansible-rulebook
Quelques cas d’utilisations d’Ansible
Vous avez aussi à votre disposition quelques exemples d’utilisation d’Ansible pour :
- Construire des images docker avec un playbook ansible
- Piloter des containers docker
- utiliser mysql comme inventaire statique
- Comment gérer plusieurs versions d’Ansible
- Vagrant et Ansible
- Installer un cluster Kubernetes avec Kubespray
- Création du home lab Devops
- Installer PowerDNS dans le home lab
- Installer Nexus dans le homelab
- Installer Rundeck dans le homelab
- Optimiser le temps de build des images Docker utilisant Ansible
- Installation d’Ansible sur Nixos
- Automatiser la mise à jour de vos collections avec Molecule/Renovate