Introduction
Ansible est un outil d'automatisation puissant qui aide les administrateurs système et les développeurs à gérer l'infrastructure de manière efficace. Lors de l'exécution de scripts ou de commandes via des playbooks Ansible, il est souvent crucial de capturer et d'afficher leur sortie à des fins de surveillance et de dépannage.
Dans ce laboratoire pratique, vous apprendrez comment afficher efficacement la sortie des scripts dans vos playbooks Ansible. Nous commencerons par les bases de la structure d'un playbook Ansible, puis explorerons diverses techniques pour capturer et afficher les sorties de commandes, et enfin, nous aborderons des méthodes avancées pour formater et filtrer les données de sortie.
À la fin de ce laboratoire, vous aurez une expérience pratique avec différentes approches pour gérer la sortie des scripts dans Ansible, ce qui vous permettra de créer des flux de travail d'automatisation plus informatifs et plus faciles à déboguer.
Configuration de votre premier playbook Ansible
Avant de pouvoir explorer comment afficher la sortie des scripts, nous devons configurer un environnement Ansible de base et créer notre premier playbook.
Installation d'Ansible
Commençons par nous assurer qu'Ansible est installé sur notre système :
sudo apt update
sudo apt install -y ansible
Cette commande installera Ansible sur votre système Ubuntu. Une fois l'installation terminée, vérifiez-la en vérifiant la version d'Ansible :
ansible --version
Vous devriez voir une sortie similaire à la suivante, ce qui confirme qu'Ansible est correctement installé :
ansible [core 2.12.x]
config file = /etc/ansible/ansible.cfg
configured module search path = ['/home/labex/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3/dist-packages/ansible
ansible collection location = /home/labex/.ansible/collections:/usr/share/ansible/collections
executable location = /usr/bin/ansible
python version = 3.10.x (default, Mar 14 2023, 14:50:41) [GCC 11.3.0]
jinja version = 3.0.3
libyaml = True
Comprendre l'inventaire Ansible
Ansible doit savoir à quels hôtes se connecter. Pour ce laboratoire, nous utiliserons un simple fichier d'inventaire qui inclut uniquement la machine locale.
Créez un répertoire pour notre projet Ansible :
mkdir -p ~/project/ansible-lab
cd ~/project/ansible-lab
Maintenant, créez un fichier d'inventaire nommé inventory.ini :
echo "localhost ansible_connection=local" > inventory.ini
Ce fichier d'inventaire indique à Ansible d'exécuter les commandes sur la machine locale sans utiliser SSH.
Création de votre premier playbook
Maintenant, créons un playbook Ansible de base. Dans le WebIDE, créez un nouveau fichier appelé first_playbook.yml dans le répertoire ~/project/ansible-lab avec le contenu suivant :
---
- name: My First Ansible Playbook
hosts: localhost
gather_facts: yes
tasks:
- name: Display a simple message
debug:
msg: "Hello from Ansible!"
- name: Display system information
debug:
msg: "You are running {{ ansible_distribution }} {{ ansible_distribution_version }}"
Ce playbook simple comporte deux tâches :
- Afficher un simple message de salutation
- Afficher des informations sur le système d'exploitation que vous utilisez
Exécutons ce playbook pour voir comment il fonctionne :
cd ~/project/ansible-lab
ansible-playbook -i inventory.ini first_playbook.yml
Vous devriez voir une sortie similaire à celle-ci :
PLAY [My First Ansible Playbook] *********************************************************
TASK [Gathering Facts] *******************************************************************
ok: [localhost]
TASK [Display a simple message] **********************************************************
ok: [localhost] => {
"msg": "Hello from Ansible!"
}
TASK [Display system information] ********************************************************
ok: [localhost] => {
"msg": "You are running Ubuntu 22.04"
}
PLAY RECAP *******************************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Cette sortie montre :
- Le playbook s'est exécuté avec succès
- Toutes les tâches se sont terminées avec le statut "ok"
- La sortie de chaque tâche de débogage est affichée
Maintenant que nous avons un playbook de base qui fonctionne, nous pouvons explorer comment exécuter des scripts et afficher leur sortie plus en détail.
Exécution de scripts et capture de la sortie
Maintenant que nous avons configuré un environnement Ansible de base, explorons comment exécuter des scripts et capturer leur sortie à l'aide des modules command et shell.
La différence entre les modules Command et Shell
Ansible fournit deux modules principaux pour l'exécution de commandes :
- command : Exécute une commande sur un nœud distant sans passer par un shell, ce qui signifie que les opérateurs shell tels que
|,>,<, et&ne fonctionnent pas. - shell : Exécute une commande via un shell, permettant l'utilisation d'opérateurs shell et de variables d'environnement.
Création d'un script simple à exécuter
Tout d'abord, créons un script shell simple que nous pourrons exécuter avec Ansible. Créez un fichier nommé system_info.sh dans votre répertoire ~/project/ansible-lab :
cd ~/project/ansible-lab
Dans le WebIDE, créez le fichier avec le contenu suivant :
#!/bin/bash
echo "=== System Information ==="
echo "Hostname: $(hostname)"
echo "Kernel Version: $(uname -r)"
echo "CPU Info: $(grep 'model name' /proc/cpuinfo | head -1 | cut -d':' -f2 | xargs)"
echo "Memory Info: $(free -h | grep Mem | awk '{print $2 " total, " $3 " used, " $4 " free"}')"
echo "Disk Usage: $(df -h / | grep / | awk '{print $5 " of " $2 " used"}')"
Rendez le script exécutable :
chmod +x ~/project/ansible-lab/system_info.sh
Maintenant, exécutons ce script manuellement pour voir quelle sortie il produit :
./system_info.sh
Vous devriez voir une sortie similaire à :
=== System Information ===
Hostname: labex-xxxxxxxx
Kernel Version: 5.15.0-xx-generic
CPU Info: Intel(R) Xeon(R) xxxxxx
Memory Info: 8.0G total, 1.2G used, 5.8G free
Disk Usage: 15% of 50G used
Exécution du script avec Ansible
Maintenant, créons un nouveau playbook qui exécutera ce script et capturera sa sortie. Créez un fichier nommé script_output.yml dans votre répertoire ~/project/ansible-lab :
---
- name: Run Script and Capture Output
hosts: localhost
gather_facts: no
tasks:
- name: Run system info script
command: ./system_info.sh
register: script_result
- name: Display script output
debug:
msg: "{{ script_result.stdout }}"
Ce playbook fait deux choses :
- Exécute notre script
system_info.shen utilisant le modulecommand - Stocke la sortie dans une variable appelée
script_resulten utilisant le mot-cléregister - Affiche la sortie capturée en utilisant le module
debug
Exécutons ce playbook :
cd ~/project/ansible-lab
ansible-playbook -i inventory.ini script_output.yml
Vous devriez voir une sortie similaire à :
PLAY [Run Script and Capture Output] ***************************************************
TASK [Run system info script] ***********************************************************
changed: [localhost]
TASK [Display script output] ************************************************************
ok: [localhost] => {
"msg": "=== System Information ===\nHostname: labex-xxxxxxxx\nKernel Version: 5.15.0-xx-generic\nCPU Info: Intel(R) Xeon(R) xxxxxx\nMemory Info: 8.0G total, 1.2G used, 5.8G free\nDisk Usage: 15% of 50G used"
}
PLAY RECAP *****************************************************************************
localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Remarquez comment la sortie apparaît sous forme d'une seule chaîne avec des caractères de nouvelle ligne (\n). Améliorons l'affichage dans la section suivante.
Comprendre la variable Register
Le mot-clé register crée une variable qui contient plusieurs attributs, et pas seulement la sortie de la commande. Créons un nouveau playbook pour explorer ces attributs.
Créez un fichier nommé register_details.yml dans votre répertoire ~/project/ansible-lab :
---
- name: Explore Register Variable
hosts: localhost
gather_facts: no
tasks:
- name: Run system info script
command: ./system_info.sh
register: script_result
- name: Display all register properties
debug:
var: script_result
- name: Display just stdout
debug:
var: script_result.stdout
- name: Display stdout as a list of lines
debug:
var: script_result.stdout_lines
Exécutez ce playbook :
ansible-playbook -i inventory.ini register_details.yml
Vous verrez une sortie plus détaillée qui montre toutes les propriétés de la variable script_result, notamment :
stdout: La sortie standard sous forme d'une seule chaînestderr: L'erreur standard (le cas échéant)rc: Le code de retour (0 signifie succès)stdout_lines: La sortie standard divisée en une liste de lignes
La dernière tâche est particulièrement utile car elle formate la sortie sous forme de liste de lignes, ce qui la rend beaucoup plus lisible.
Techniques avancées de gestion de la sortie
Maintenant que nous comprenons les bases de la capture de la sortie des scripts, explorons des techniques plus avancées pour gérer et afficher la sortie dans les playbooks Ansible.
Gestion des erreurs de script
Lors de l'exécution de scripts, il est important de gérer correctement les conditions d'erreur. Ansible marque une tâche comme ayant échoué si la commande renvoie un code de sortie différent de zéro. Créons un playbook qui démontre la gestion des erreurs.
Créez un fichier nommé error_handling.yml dans votre répertoire ~/project/ansible-lab :
---
- name: Handling Script Errors
hosts: localhost
gather_facts: no
tasks:
- name: Run a command that might fail
command: ls /nonexistent_directory
register: cmd_result
ignore_errors: yes
- name: Show error message if command failed
debug:
msg: "Command failed with error: {{ cmd_result.stderr }}"
when: cmd_result.rc != 0
- name: Show success message if command succeeded
debug:
msg: "Command succeeded with output: {{ cmd_result.stdout }}"
when: cmd_result.rc == 0
Dans ce playbook :
- Nous tentons de lister un répertoire qui n'existe pas
- Nous utilisons
ignore_errors: yespour empêcher le playbook de s'arrêter si la commande échoue - Nous vérifions le code de retour (
cmd_result.rc) pour déterminer si la commande a réussi ou échoué - Nous affichons les messages appropriés en fonction du résultat
Exécutons ce playbook :
cd ~/project/ansible-lab
ansible-playbook -i inventory.ini error_handling.yml
Vous devriez voir une sortie similaire à :
PLAY [Handling Script Errors] ***********************************************************
TASK [Run a command that might fail] ***************************************************
fatal: [localhost]: FAILED! => {"changed": true, "cmd": ["ls", "/nonexistent_directory"], "delta": "0:00:00.003398", "end": "2023-09-15 12:34:56.789012", "msg": "non-zero return code", "rc": 2, "start": "2023-09-15 12:34:56.785614", "stderr": "ls: cannot access '/nonexistent_directory': No such file or directory", "stderr_lines": ["ls: cannot access '/nonexistent_directory': No such file or directory"], "stdout": "", "stdout_lines": []}
...ignoring
TASK [Show error message if command failed] *********************************************
ok: [localhost] => {
"msg": "Command failed with error: ls: cannot access '/nonexistent_directory': No such file or directory"
}
TASK [Show success message if command succeeded] ****************************************
skipping: [localhost]
PLAY RECAP *******************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=1
Remarquez que malgré l'échec de la commande, le playbook continue de s'exécuter et affiche le message d'erreur.
Formatage de la sortie multiligne
Créons un script plus complexe qui génère une sortie multiligne, puis formatons-la correctement dans notre playbook.
Créez un fichier nommé package_info.sh dans votre répertoire ~/project/ansible-lab :
#!/bin/bash
echo "TOP 5 LARGEST INSTALLED PACKAGES"
echo "================================"
dpkg-query -W -f='${Installed-Size}\t${Package}\n' | sort -n -r | head -5
Rendez-le exécutable :
chmod +x ~/project/ansible-lab/package_info.sh
Maintenant, créez un playbook pour exécuter ce script et formater correctement la sortie. Créez un fichier nommé formatted_output.yml :
---
- name: Format Script Output
hosts: localhost
gather_facts: no
tasks:
- name: Run package info script
shell: ./package_info.sh
register: pkg_info
- name: Display raw output
debug:
msg: "{{ pkg_info.stdout }}"
- name: Display formatted output with a title
debug:
msg: |
Below is the package information:
--------------------------------
{% for line in pkg_info.stdout_lines %}
{{ line }}
{% endfor %}
--------------------------------
Total lines: {{ pkg_info.stdout_lines | length }}
Ce playbook :
- Exécute notre script
package_info.sh - Affiche la sortie brute
- Utilise un modèle Jinja2 pour formater la sortie avec un titre et un pied de page
Exécutons-le :
ansible-playbook -i inventory.ini formatted_output.yml
Vous devriez voir une sortie correctement formatée :
PLAY [Format Script Output] ***********************************************************
TASK [Run package info script] ********************************************************
changed: [localhost]
TASK [Display raw output] *************************************************************
ok: [localhost] => {
"msg": "TOP 5 LARGEST INSTALLED PACKAGES\n================================\n112233\tsome-large-package\n99887\tanother-package\n...\n"
}
TASK [Display formatted output with a title] ******************************************
ok: [localhost] => {
"msg": "Below is the package information:\n--------------------------------\nTOP 5 LARGEST INSTALLED PACKAGES\n================================\n112233\tsome-large-package\n99887\tanother-package\n...\n--------------------------------\nTotal lines: 7"
}
PLAY RECAP ****************************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Affichage conditionnel de la sortie
Parfois, vous ne souhaitez afficher la sortie que dans certaines conditions, par exemple lors de l'exécution en mode verbeux. Voyons comment faire cela.
Créez un fichier nommé conditional_output.yml dans votre répertoire ~/project/ansible-lab :
---
- name: Conditional Output Display
hosts: localhost
gather_facts: yes
tasks:
- name: Get disk usage information
shell: df -h
register: disk_info
- name: Display disk usage (always shown)
debug:
msg: "{{ disk_info.stdout_lines[0:2] }}"
- name: Display detailed disk usage (only in verbose mode)
debug:
msg: "{{ disk_info.stdout_lines }}"
verbosity: 1
Dans ce playbook :
- Nous capturons les informations d'utilisation du disque
- Nous affichons toujours un résumé (deux premières lignes)
- Nous affichons les détails complets uniquement lors de l'exécution en mode verbeux (avec l'option
-v)
Exécutons-le d'abord en mode normal :
ansible-playbook -i inventory.ini conditional_output.yml
Maintenant, exécutons-le en mode verbeux :
ansible-playbook -i inventory.ini conditional_output.yml -v
Vous remarquerez qu'en mode verbeux, vous obtenez les informations complètes sur l'utilisation du disque, tandis qu'en mode normal, vous ne voyez que le résumé.
Cette technique est utile pour masquer par défaut une sortie potentiellement sensible ou accablante, tout en la rendant disponible en cas de besoin pour le débogage.
Résumé
Dans ce lab, vous avez appris diverses techniques pour capturer et afficher la sortie de scripts dans les playbooks Ansible :
- Vous avez configuré un environnement Ansible de base et créé votre premier playbook
- Vous avez appris à exécuter des scripts en utilisant les modules
commandetshell - Vous avez capturé la sortie des scripts en utilisant la directive
register - Vous avez affiché la sortie en utilisant le module
debugdans différents formats - Vous avez géré les conditions d'erreur et mis en œuvre l'affichage conditionnel de la sortie
- Vous avez appliqué des techniques de formatage pour rendre la sortie plus lisible
Ces compétences vous permettent de créer des playbooks Ansible plus informatifs qui fournissent des commentaires clairs pendant l'exécution. Cette visibilité est cruciale à la fois pour la surveillance des processus automatisés et pour le dépannage en cas de problèmes.
En tirant parti de ces techniques de gestion de la sortie, vous pouvez construire des flux de travail d'automatisation plus robustes qui non seulement exécutent des tâches, mais communiquent également clairement ce qui se passe à chaque étape. Cela rend votre automatisation plus transparente et plus facile à maintenir, en particulier lorsque vous travaillez en équipe ou avec une infrastructure complexe.


