Aller au contenu principal

Maîtriser Ansible

Logo Ansible

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.

Que vous soyez un vétéran aguerri d'Ansible ou que vous découvriez tout juste cette technologie, cette documentation est là pour vous aider à maitriser 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 de rétroaction 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 qu'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 ses composants qui est la version disponible en Open Source. Sa version commerciale, connue sous le nom de d'Ansible Tower a été renommé en Automation Controller. Si vous voulez plus d'informations sur AWX, vous trouverez en bas de ce billet une belle série de liens.

Comment fonctionne Ansible ?

Contrairement aux idées reçues pour apprendre à développer du code Ansible, il n'y a pas besoin de déployer un serveur 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éfini 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.

Ansible

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é, en théorie, que sur des ordinateurs fonctionnant sur les systèmes d’exploitation Linux et MacOS. La manière la plus propre pour installer d’Ansible 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 pip3 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 chiffrer 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.

Qu'est-ce qu'un inventaire ansible ?

Ici ne sera abordé que la notion d’inventaire statique ansible.

L’inventaire statique sous Ansible est un fichier lus souvent 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 la description (name) est update web servers
  • qui cible les hosts du groupe webservers
  • qui demande l'élévation de privilège (become) pour exécuter des tâches les nécessitant.
  • qui 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 ---.

Plus d'infos sur le langage YAML

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 :

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

Quelques outils complémentaires à Ansible

Quelques cas d'utilisations d'Ansible

Vous avez aussi à votre disposition quelques exemples d'utilisation d'Ansible pour :

Plus d'infos

Livres Gratuits

Livres

MOOC

Sites

Videos