Introduction
Ansible est un outil d'automatisation open-source puissant, largement utilisé par les administrateurs système et les professionnels DevOps. L'une de ses capacités clés est l'exécution de commandes shell sur des hôtes distants et le traitement de leur sortie. Dans ce tutoriel pratique, vous apprendrez comment capturer, afficher et traiter efficacement la sortie des commandes shell dans les playbooks Ansible. Cette compétence est essentielle pour créer des flux de travail d'automatisation robustes, capables de s'adapter à différentes conditions système et de fournir des retours d'information utiles.
Configuration de votre premier playbook Ansible avec des commandes Shell
Dans cette étape, nous allons configurer un playbook Ansible de base qui exécute des commandes shell et capture leur sortie. Cela fournira les bases pour des techniques plus avancées dans les étapes suivantes.
Installation d'Ansible
Tout d'abord, installons Ansible sur notre système :
sudo apt update
sudo apt install -y ansible
Maintenant, vérifiez qu'Ansible est correctement installé :
ansible --version
Vous devriez voir une sortie similaire à celle-ci :
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 15 2022, 12:22:08) [GCC 11.2.0]
jinja version = 3.0.3
libyaml = True
Création d'un fichier d'inventaire
Ansible utilise un fichier d'inventaire pour savoir quels hôtes gérer. Pour ce lab, nous allons créer un inventaire simple qui inclut uniquement la machine locale :
- Ouvrez votre WebIDE et créez un nouveau fichier appelé
inventory.inidans le répertoire/home/labex/project. - Ajoutez le contenu suivant au fichier :
[local]
localhost ansible_connection=local
Cet inventaire définit un groupe appelé local qui contient uniquement localhost, et indique à Ansible de se connecter directement sans SSH.
Création de votre premier Playbook
Maintenant, créons un playbook simple qui exécute des commandes shell :
- Créez un nouveau fichier appelé
first_playbook.ymldans le répertoire/home/labex/project. - Ajoutez le contenu YAML suivant au fichier :
---
- name: Shell Command Example
hosts: local
gather_facts: no
tasks:
- name: Run a simple shell command
shell: echo "Hello from Ansible shell command"
register: hello_output
- name: Display the output
debug:
msg: "{{ hello_output.stdout }}"
Ce playbook fait ce qui suit :
- Cible le groupe
localque nous avons défini dans notre inventaire - Ignore la collecte des faits (informations système) pour simplifier les choses
- Exécute une commande shell qui affiche un message de salutation
- Stocke la sortie dans une variable en utilisant le mot-clé
register - Affiche la sortie en utilisant le module
debug
Exécution de votre Playbook
Maintenant, exécutons le playbook :
ansible-playbook -i inventory.ini first_playbook.yml
Vous devriez voir une sortie similaire à celle-ci :
PLAY [Shell Command Example] **************************************************
TASK [Run a simple shell command] *********************************************
changed: [localhost]
TASK [Display the output] *****************************************************
ok: [localhost] => {
"msg": "Hello from Ansible shell command"
}
PLAY RECAP ********************************************************************
localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
La sortie montre que notre playbook s'est exécuté avec succès, exécutant la commande shell et affichant sa sortie.
Concepts clés à comprendre
De cet exercice, notez ces concepts importants :
- Le module
shellvous permet d'exécuter des commandes shell - La directive
registercapture la sortie d'une tâche dans une variable - Le module
debugaide à afficher les valeurs des variables - La sortie des commandes shell contient à la fois
stdout(sortie standard) etstderr(sortie d'erreur)
Dans l'étape suivante, nous explorerons comment traiter et formater la sortie des commandes shell plus efficacement.
Travailler avec la sortie structurée des commandes Shell
Maintenant que vous comprenez les bases de l'exécution des commandes shell dans Ansible, explorons comment travailler avec la sortie structurée des commandes et l'afficher dans différents formats.
Traitement des informations système
Créons un playbook plus pratique qui collecte des informations système et les présente de manière structurée :
- Créez un nouveau fichier appelé
system_info.ymldans le répertoire/home/labex/project. - Ajoutez le contenu suivant :
---
- name: Gather and Display System Information
hosts: local
gather_facts: no
tasks:
- name: Gather system information
shell: |
echo "OS Information: $(cat /etc/os-release | grep PRETTY_NAME | cut -d= -f2)"
echo "Kernel Version: $(uname -r)"
echo "CPU Information: $(grep "model name" /proc/cpuinfo | head -1 | cut -d: -f2 | xargs)"
echo "Memory Information: $(free -h | grep Mem | awk '{print $2}')"
register: system_info
- name: Display raw system information
debug:
msg: "{{ system_info.stdout }}"
- name: Display information as a list
debug:
msg: "{{ system_info.stdout_lines }}"
Ce playbook :
- Exécute un script shell multiligne qui collecte diverses informations système
- Stocke la sortie dans la variable
system_info - Affiche la sortie d'abord sous forme de chaîne brute, puis sous forme de liste de lignes
Exécutez le playbook :
ansible-playbook -i inventory.ini system_info.yml
Vous devriez voir une sortie qui ressemble à ceci :
PLAY [Gather and Display System Information] **********************************
TASK [Gather system information] **********************************************
changed: [localhost]
TASK [Display raw system information] *****************************************
ok: [localhost] => {
"msg": "OS Information: \"Ubuntu 22.04.1 LTS\"\nKernel Version: 5.15.0-1023-azure\nCPU Information: Intel(R) Xeon(R) Platinum 8171M CPU @ 2.60GHz\nMemory Information: 4.0Gi"
}
TASK [Display information as a list] *****************************************
ok: [localhost] => {
"msg": [
"OS Information: \"Ubuntu 22.04.1 LTS\"",
"Kernel Version: 5.15.0-1023-azure",
"CPU Information: Intel(R) Xeon(R) Platinum 8171M CPU @ 2.60GHz",
"Memory Information: 4.0Gi"
]
}
PLAY RECAP ********************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Remarquez comment la deuxième tâche d'affichage montre la sortie sous forme de liste au lieu d'une chaîne avec des sauts de ligne. Ce format de liste facilite le travail avec une sortie multiligne.
Travailler avec les résultats de commandes et les codes de retour
Les commandes shell sous Linux renvoient des codes de sortie pour indiquer le succès (0) ou l'échec (non nul). Ansible les capture dans l'attribut rc (return code) de la variable enregistrée.
Créons un playbook qui démontre comment travailler avec les codes de retour :
- Créez un nouveau fichier appelé
command_results.ymldans le répertoire/home/labex/project. - Ajoutez le contenu suivant :
---
- name: Working with Command Results
hosts: local
gather_facts: no
tasks:
- name: Check if a file exists
shell: test -f /etc/hosts
register: file_check
ignore_errors: yes
- name: Show command result details
debug:
msg: |
Return code: {{ file_check.rc }}
Succeeded: {{ file_check.rc == 0 }}
Failed: {{ file_check.rc != 0 }}
- name: Check if a non-existent file exists
shell: test -f /file/does/not/exist
register: missing_file
ignore_errors: yes
- name: Show command result for missing file
debug:
msg: |
Return code: {{ missing_file.rc }}
Succeeded: {{ missing_file.rc == 0 }}
Failed: {{ missing_file.rc != 0 }}
Ce playbook :
- Exécute deux commandes de test pour vérifier si des fichiers existent
- Utilise
ignore_errors: yespour empêcher le playbook de s'arrêter si une commande échoue - Affiche des informations détaillées sur les résultats de la commande, y compris le code de retour et l'état de réussite/échec
Exécutez le playbook :
ansible-playbook -i inventory.ini command_results.yml
Vous devriez voir une sortie similaire à ceci :
PLAY [Working with Command Results] *******************************************
TASK [Check if a file exists] *************************************************
changed: [localhost]
TASK [Show command result details] ********************************************
ok: [localhost] => {
"msg": "Return code: 0\nSucceeded: True\nFailed: False\n"
}
TASK [Check if a non-existent file exists] ************************************
fatal: [localhost]: FAILED! => {"changed": true, "cmd": "test -f /file/does/not/exist", "delta": "0:00:00.003183", "end": "2023-07-14 15:24:33.931406", "msg": "non-zero return code", "rc": 1, "start": "2023-07-14 15:24:33.928223", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
...ignoring
TASK [Show command result for missing file] ***********************************
ok: [localhost] => {
"msg": "Return code: 1\nSucceeded: False\nFailed: True\n"
}
PLAY RECAP ********************************************************************
localhost : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
Remarquez comment le code de retour est 0 pour le fichier existant et 1 pour le fichier inexistant. Cela démontre comment vous pouvez utiliser les codes de retour pour prendre des décisions dans vos playbooks.
Comprendre la structure de la variable enregistrée
La variable enregistrée à partir d'une commande shell contient plusieurs attributs utiles :
stdout: La sortie standard sous forme de chaîne uniquestdout_lines: La sortie standard divisée en une liste de lignesstderr: La sortie d'erreur standard sous forme de chaîne uniquestderr_lines: La sortie d'erreur standard divisée en une liste de lignesrc: Le code de retour (0 pour le succès, non nul pour l'échec)cmd: La commande qui a été exécutéestartetend: Horodatages pour le début et la fin de la commandedelta: La durée de l'exécution de la commande
Comprendre cette structure est crucial pour travailler efficacement avec la sortie des commandes shell dans Ansible.
Exécution conditionnelle basée sur la sortie shell
L'une des capacités les plus puissantes d'Ansible est la possibilité de prendre des décisions basées sur la sortie des commandes shell. Dans cette étape, nous allons apprendre à utiliser des conditions et des filtres pour traiter la sortie des commandes shell et rendre les playbooks plus dynamiques.
Utilisation des conditions avec la sortie shell
Créons un playbook qui prend des décisions basées sur la sortie des commandes shell :
- Créez un nouveau fichier appelé
conditional_playbook.ymldans le répertoire/home/labex/project. - Ajoutez le contenu suivant :
---
- name: Conditional Tasks Based on Command Output
hosts: local
gather_facts: no
tasks:
- name: Check disk space
shell: df -h / | grep -v Filesystem | awk '{print $5}' | sed 's/%//'
register: disk_usage
- name: Display disk usage
debug:
msg: "Current disk usage: {{ disk_usage.stdout }}%"
- name: Disk usage warning
debug:
msg: "WARNING: Disk usage is high"
when: disk_usage.stdout|int > 50
- name: Disk usage normal
debug:
msg: "Disk usage is normal"
when: disk_usage.stdout|int <= 50
Ce playbook :
- Exécute une commande shell pour vérifier le pourcentage d'utilisation du disque sur le système de fichiers racine
- Utilise la condition
whenbasée sur la sortie de la commande - Utilise le filtre
intpour convertir la sortie de la chaîne en un entier pour la comparaison
Exécutez le playbook :
ansible-playbook -i inventory.ini conditional_playbook.yml
La sortie variera en fonction de votre utilisation réelle du disque, mais ressemblera à ceci :
PLAY [Conditional Tasks Based on Command Output] ******************************
TASK [Check disk space] *******************************************************
changed: [localhost]
TASK [Display disk usage] *****************************************************
ok: [localhost] => {
"msg": "Current disk usage: 38%"
}
TASK [Disk usage warning] *****************************************************
skipped: [localhost]
TASK [Disk usage normal] ******************************************************
ok: [localhost] => {
"msg": "Disk usage is normal"
}
PLAY RECAP ********************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
Remarquez comment Ansible a exécuté une seule des tâches conditionnelles en fonction de la valeur réelle de l'utilisation du disque.
Gestion de la sortie JSON des commandes
De nombreux outils CLI modernes renvoient des données au format JSON. Ansible possède des capacités intégrées pour gérer la sortie JSON :
- Créez un nouveau fichier appelé
json_output.ymldans le répertoire/home/labex/project. - Ajoutez le contenu suivant :
---
- name: Handling JSON Output
hosts: local
gather_facts: no
tasks:
- name: Create a JSON file for testing
copy:
dest: /tmp/services.json
content: |
{
"services": [
{
"name": "web",
"status": "running",
"port": 80
},
{
"name": "database",
"status": "stopped",
"port": 5432
},
{
"name": "cache",
"status": "running",
"port": 6379
}
]
}
- name: Read JSON file with shell
shell: cat /tmp/services.json
register: json_output
- name: Parse and display JSON content
debug:
msg: "{{ json_output.stdout | from_json }}"
- name: Extract and display service information
debug:
msg: "Service: {{ item.name }}, Status: {{ item.status }}, Port: {{ item.port }}"
loop: "{{ (json_output.stdout | from_json).services }}"
- name: Show only running services
debug:
msg: "Running service: {{ item.name }} on port {{ item.port }}"
loop: "{{ (json_output.stdout | from_json).services }}"
when: item.status == "running"
Ce playbook :
- Crée un exemple de fichier JSON pour la démonstration
- Lit le fichier JSON avec une commande shell
- Utilise le filtre
from_jsonpour analyser la chaîne JSON en une structure de données - Parcourt la structure de données pour afficher les informations
- Utilise une logique conditionnelle pour filtrer uniquement les services en cours d'exécution
Exécutez le playbook :
ansible-playbook -i inventory.ini json_output.yml
Vous devriez voir une sortie similaire à ceci :
PLAY [Handling JSON Output] ***************************************************
TASK [Create a JSON file for testing] *****************************************
changed: [localhost]
TASK [Read JSON file with shell] **********************************************
changed: [localhost]
TASK [Parse and display JSON content] *****************************************
ok: [localhost] => {
"msg": {
"services": [
{
"name": "web",
"port": 80,
"status": "running"
},
{
"name": "database",
"port": 5432,
"status": "stopped"
},
{
"name": "cache",
"port": 6379,
"status": "running"
}
]
}
}
TASK [Extract and display service information] ********************************
ok: [localhost] => (item={'name': 'web', 'status': 'running', 'port': 80}) => {
"msg": "Service: web, Status: running, Port: 80"
}
ok: [localhost] => (item={'name': 'database', 'status': 'stopped', 'port': 5432}) => {
"msg": "Service: database, Status: stopped, Port: 5432"
}
ok: [localhost] => (item={'name': 'cache', 'status': 'running', 'port': 6379}) => {
"msg": "Service: cache, Status: running, Port: 6379"
}
TASK [Show only running services] *********************************************
ok: [localhost] => (item={'name': 'web', 'status': 'running', 'port': 80}) => {
"msg": "Running service: web on port 80"
}
skipped: [localhost] => (item={'name': 'database', 'status': 'stopped', 'port': 5432})
ok: [localhost] => (item={'name': 'cache', 'status': 'running', 'port': 6379}) => {
"msg": "Running service: cache on port 6379"
}
PLAY RECAP ********************************************************************
localhost : ok=5 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Remarquez comment le playbook analyse le JSON, extrait des informations spécifiques et filtre les données en fonction des conditions.
Gestion des erreurs avec les commandes shell
Lors de l'exécution de commandes shell, il est important de gérer les erreurs potentielles avec élégance :
- Créez un nouveau fichier appelé
error_handling.ymldans le répertoire/home/labex/project. - Ajoutez le contenu suivant :
---
- name: Error Handling with Shell Commands
hosts: local
gather_facts: no
tasks:
- name: Run a potentially failing command
shell: grep "nonexistent_pattern" /etc/passwd
register: command_result
ignore_errors: yes
- name: Display success or failure
debug:
msg: "Command {{ 'succeeded' if command_result.rc == 0 else 'failed with return code ' + command_result.rc|string }}"
- name: Run a custom failing command
shell: exit 3
register: exit_command
ignore_errors: yes
- name: Display detailed error information
debug:
msg: |
Return code: {{ exit_command.rc }}
Error message: {{ exit_command.stderr if exit_command.stderr else 'No error message' }}
Ce playbook :
- Exécute des commandes qui sont censées échouer
- Utilise
ignore_errors: yespour continuer l'exécution du playbook même lorsque les commandes échouent - Montre différentes méthodes pour gérer et afficher les informations d'erreur
Exécutez le playbook :
ansible-playbook -i inventory.ini error_handling.yml
Vous devriez voir une sortie similaire à ceci :
PLAY [Error Handling with Shell Commands] *************************************
TASK [Run a potentially failing command] **************************************
fatal: [localhost]: FAILED! => {"changed": true, "cmd": "grep \"nonexistent_pattern\" /etc/passwd", "delta": "0:00:00.002916", "end": "2023-07-14 16:10:23.671519", "msg": "non-zero return code", "rc": 1, "start": "2023-07-14 16:10:23.668603", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
...ignoring
TASK [Display success or failure] *********************************************
ok: [localhost] => {
"msg": "Command failed with return code 1"
}
TASK [Run a custom failing command] *******************************************
fatal: [localhost]: FAILED! => {"changed": true, "cmd": "exit 3", "delta": "0:00:00.002447", "end": "2023-07-14 16:10:23.906121", "msg": "non-zero return code", "rc": 3, "start": "2023-07-14 16:10:23.903674", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
...ignoring
TASK [Display detailed error information] *************************************
ok: [localhost] => {
"msg": "Return code: 3\nError message: No error message\n"
}
PLAY RECAP ********************************************************************
localhost : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=2
Cela démontre comment capturer et répondre à différentes conditions d'erreur lors de l'exécution de commandes shell.
Création d'un outil pratique de traitement de la sortie shell
Dans cette dernière étape, nous allons rassembler tout ce que nous avons appris pour créer un playbook Ansible pratique qui collecte des informations système, les traite et génère un rapport. Cela représente un scénario réel où les capacités de traitement des commandes shell d'Ansible peuvent être extrêmement utiles.
Construction d'un outil de rapport d'informations système
Créons un outil complet de collecte d'informations système :
- Créez un nouveau fichier appelé
system_report.ymldans le répertoire/home/labex/project. - Ajoutez le contenu suivant :
---
- name: Comprehensive System Report
hosts: local
gather_facts: no
vars:
report_file: /tmp/system_report.txt
tasks:
- name: Collect basic system information
shell: |
echo "SYSTEM REPORT" > {{ report_file }}
echo "=============" >> {{ report_file }}
echo "" >> {{ report_file }}
echo "HOSTNAME: $(hostname)" >> {{ report_file }}
echo "TIMESTAMP: $(date)" >> {{ report_file }}
echo "" >> {{ report_file }}
echo "SYSTEM INFORMATION" >> {{ report_file }}
echo "------------------" >> {{ report_file }}
echo "OS: $(cat /etc/os-release | grep PRETTY_NAME | cut -d= -f2)" >> {{ report_file }}
echo "KERNEL: $(uname -r)" >> {{ report_file }}
echo "UPTIME: $(uptime -p)" >> {{ report_file }}
echo "" >> {{ report_file }}
echo "RESOURCE UTILIZATION" >> {{ report_file }}
echo "-------------------" >> {{ report_file }}
echo "CPU LOAD: $(uptime | awk -F'load average:' '{print $2}')" >> {{ report_file }}
echo "MEMORY USAGE:" >> {{ report_file }}
free -h >> {{ report_file }}
echo "" >> {{ report_file }}
echo "DISK USAGE:" >> {{ report_file }}
df -h >> {{ report_file }}
echo "" >> {{ report_file }}
echo "NETWORK INFORMATION" >> {{ report_file }}
echo "-------------------" >> {{ report_file }}
echo "IP ADDRESSES:" >> {{ report_file }}
ip addr | grep "inet " | awk '{print $2}' >> {{ report_file }}
echo "" >> {{ report_file }}
echo "PROCESS INFORMATION" >> {{ report_file }}
echo "-------------------" >> {{ report_file }}
echo "TOP 5 CPU CONSUMING PROCESSES:" >> {{ report_file }}
ps aux --sort=-%cpu | head -6 >> {{ report_file }}
echo "" >> {{ report_file }}
echo "TOP 5 MEMORY CONSUMING PROCESSES:" >> {{ report_file }}
ps aux --sort=-%mem | head -6 >> {{ report_file }}
register: report_generation
- name: Check if report was generated successfully
stat:
path: "{{ report_file }}"
register: report_stat
- name: Display report generation status
debug:
msg: "Report generated successfully at {{ report_file }}"
when: report_stat.stat.exists
- name: Display report content
shell: cat {{ report_file }}
register: report_content
when: report_stat.stat.exists
- name: Show report content
debug:
msg: "{{ report_content.stdout_lines }}"
when: report_stat.stat.exists
- name: Analyze disk usage
shell: df -h / | grep -v Filesystem | awk '{print $5}' | sed 's/%//'
register: disk_usage
when: report_stat.stat.exists
- name: Generate disk usage alert if needed
debug:
msg: "ALERT: Disk usage on / is {{ disk_usage.stdout }}% which exceeds the 80% threshold!"
when:
- report_stat.stat.exists
- disk_usage.stdout|int > 80
- name: Generate disk usage warning if needed
debug:
msg: "WARNING: Disk usage on / is {{ disk_usage.stdout }}% which exceeds the 60% threshold."
when:
- report_stat.stat.exists
- disk_usage.stdout|int > 60
- disk_usage.stdout|int <= 80
- name: Confirm normal disk usage
debug:
msg: "Disk usage on / is normal at {{ disk_usage.stdout }}%."
when:
- report_stat.stat.exists
- disk_usage.stdout|int <= 60
Ce playbook :
- Collecte des informations système complètes à l'aide d'une série de commandes shell
- Écrit les informations dans un fichier de rapport
- Vérifie que le rapport a été créé avec succès
- Affiche le contenu du rapport
- Analyse les données d'utilisation du disque
- Génère des alertes appropriées en fonction de l'analyse
Exécutez le playbook :
ansible-playbook -i inventory.ini system_report.yml
Vous verrez une sortie complète montrant l'exécution du playbook et le rapport système complet. La sortie est assez longue, voici donc juste un exemple de ce que vous pourriez voir :
PLAY [Comprehensive System Report] ********************************************
TASK [Collect basic system information] ***************************************
changed: [localhost]
TASK [Check if report was generated successfully] *****************************
ok: [localhost]
TASK [Display report generation status] ***************************************
ok: [localhost] => {
"msg": "Report generated successfully at /tmp/system_report.txt"
}
TASK [Display report content] *************************************************
changed: [localhost]
TASK [Show report content] ****************************************************
ok: [localhost] => {
"msg": [
"SYSTEM REPORT",
"=============",
"",
"HOSTNAME: ubuntu-vm",
"TIMESTAMP: Fri Jul 14 16:35:42 UTC 2023",
"",
"SYSTEM INFORMATION",
"------------------",
"OS: \"Ubuntu 22.04.1 LTS\"",
"KERNEL: 5.15.0-1023-azure",
"UPTIME: up 3 hours, 25 minutes",
...
Examen du rapport
Examinons le rapport système que nous avons généré :
cat /tmp/system_report.txt
Cela affichera le rapport complet qui a été généré par notre playbook.
Création d'un script shell personnalisé et appel depuis Ansible
Pour les opérations plus complexes, il est parfois plus facile de créer un script shell dédié et de l'appeler depuis Ansible :
- Créez un nouveau fichier appelé
disk_analyzer.shdans le répertoire/home/labex/project. - Ajoutez le contenu suivant :
#!/bin/bash
## disk_analyzer.sh - A simple script to analyze disk usage
echo "DISK USAGE ANALYSIS"
echo "------------------"
## Get overall disk usage
ROOT_USAGE=$(df -h / | grep -v Filesystem | awk '{print $5}' | sed 's/%//')
echo "Root filesystem usage: ${ROOT_USAGE}%"
## Categorize the usage
if [ $ROOT_USAGE -gt 80 ]; then
echo "STATUS: CRITICAL - Immediate action required"
elif [ $ROOT_USAGE -gt 60 ]; then
echo "STATUS: WARNING - Consider cleaning up disk space"
else
echo "STATUS: OK - Disk usage is within normal parameters"
fi
echo ""
## Find largest directories
echo "Top 5 largest directories in /var:"
du -h /var --max-depth=1 2> /dev/null | sort -hr | head -5
echo ""
## Find largest files
echo "Top 5 largest files in /var/log:"
find /var/log -type f -exec du -h {} \; 2> /dev/null | sort -hr | head -5
exit 0
- Rendez le script exécutable :
chmod +x /home/labex/project/disk_analyzer.sh
- Créez un nouveau playbook pour appeler ce script :
touch /home/labex/project/call_script.yml
- Ajoutez le contenu suivant au playbook :
---
- name: Call Custom Shell Script
hosts: local
gather_facts: no
tasks:
- name: Run disk analyzer script
shell: /home/labex/project/disk_analyzer.sh
register: script_output
- name: Display script output
debug:
msg: "{{ script_output.stdout_lines }}"
- name: Check for critical status
debug:
msg: "CRITICAL DISK USAGE DETECTED! Immediate action required."
when: script_output.stdout is search("STATUS: CRITICAL")
- Exécutez le playbook :
ansible-playbook -i inventory.ini call_script.yml
Vous devriez voir une sortie similaire à ceci :
PLAY [Call Custom Shell Script] ***********************************************
TASK [Run disk analyzer script] ***********************************************
changed: [localhost]
TASK [Display script output] **************************************************
ok: [localhost] => {
"msg": [
"DISK USAGE ANALYSIS",
"------------------",
"Root filesystem usage: 38%",
"STATUS: OK - Disk usage is within normal parameters",
"",
"Top 5 largest directories in /var:",
"60M\t/var/lib",
"60M\t/var/cache",
"12M\t/var/log",
"4.0K\t/var/tmp",
"4.0K\t/var/mail",
"",
"Top 5 largest files in /var/log:",
"4.0M\t/var/log/journal/c75af53674ce472fb9654a1d5cf8cc37/system.journal",
"2.3M\t/var/log/auth.log",
"1.3M\t/var/log/syslog",
"724K\t/var/log/kern.log",
"428K\t/var/log/cloud-init.log"
]
}
TASK [Check for critical status] **********************************************
skipped: [localhost]
PLAY RECAP ********************************************************************
localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
Cette approche combine la puissance des scripts shell avec les capacités d'automatisation d'Ansible. Le script shell gère la logique complexe pour l'analyse du disque, tandis qu'Ansible gère l'exécution et le traitement ultérieur des résultats.
Principaux points à retenir
Grâce à ce laboratoire, vous avez appris plusieurs techniques importantes pour travailler avec la sortie des commandes shell dans Ansible :
- Comment exécuter des commandes shell et capturer leur sortie
- Comment traiter et formater la sortie des commandes pour l'affichage
- Comment utiliser l'exécution conditionnelle basée sur les résultats des commandes
- Comment gérer la sortie JSON et les conditions d'erreur
- Comment créer des outils pratiques qui combinent les commandes shell avec les capacités d'automatisation d'Ansible
Ces compétences seront inestimables lorsque vous construirez des solutions d'automatisation plus complexes avec Ansible.
Résumé
Dans ce laboratoire, vous avez appris à travailler efficacement avec la sortie des commandes shell dans les playbooks Ansible. En commençant par les bases de l'exécution des commandes shell et de la capture de leur sortie, vous avez progressé vers des techniques plus avancées telles que l'exécution conditionnelle, la gestion des erreurs et le traitement des formats de données structurées comme JSON.
Vous avez maîtrisé plusieurs compétences clés :
- Exécution de commandes shell dans les playbooks Ansible à l'aide du module
shell - Capture de la sortie des commandes avec la directive
register - Affichage de la sortie à l'aide du module
debug - Traitement de la sortie avec les filtres et les conditions Jinja2
- Création d'outils d'automatisation pratiques qui combinent Ansible avec des scripts shell
Ces techniques vous permettent de créer des flux de travail d'automatisation plus dynamiques et réactifs, capables de s'adapter à différentes conditions système et de fournir des commentaires utiles sur les opérations en cours.
Au fur et à mesure que vous poursuivez votre parcours Ansible, n'oubliez pas que, bien que les commandes shell offrent une grande flexibilité, les modules intégrés d'Ansible sont souvent une solution plus robuste et portable pour les tâches courantes. Utilisez les commandes shell lorsque vous devez exploiter des scripts shell existants ou effectuer des opérations complexes qui ne sont pas facilement gérées par les modules Ansible.


