Introducción
Ansible es una herramienta de automatización de TI ampliamente utilizada que simplifica la gestión de infraestructuras complejas y la implementación de aplicaciones. En este tutorial, exploraremos cómo capturar la salida de scripts ejecutados a través de playbooks de Ansible. Esta capacidad es esencial para monitorear, depurar y analizar los resultados de sus tareas de automatización. Al final de este laboratorio, comprenderá varias técnicas para capturar y utilizar la salida de scripts en sus flujos de trabajo de Ansible.
Configuración del Entorno Ansible
Antes de que podamos comenzar a capturar la salida de scripts con Ansible, necesitamos configurar un entorno Ansible básico. Esto incluye la creación de la estructura de directorios y los archivos de configuración necesarios.
Comprensión de los Conceptos Básicos de Ansible
Ansible funciona conectándose a hosts de destino y enviando pequeños programas llamados módulos. Estos módulos se ejecutan en los hosts de destino y se eliminan cuando se completan. Ansible no requiere agentes (agent-less), lo que significa que no necesita instalar ningún software especial en los nodos administrados.
Comencemos creando un directorio de proyecto y los archivos de Ansible necesarios:
mkdir -p ~/project/ansible-output-demo/scripts
cd ~/project/ansible-output-demo
Ahora, creemos un archivo de inventario simple. En Ansible, el archivo de inventario define los hosts y grupos de hosts en los que operan los comandos, módulos y tareas en un playbook.
Cree un archivo de inventario usando el editor de código:
- Haga clic en el menú "Archivo" en la esquina superior izquierda del IDE
- Seleccione "Nuevo archivo"
- Guárdelo como
inventoryen el directorio~/project/ansible-output-demo
Agregue el siguiente contenido al archivo inventory:
[local]
localhost ansible_connection=local
Este archivo de inventario especifica que ejecutaremos Ansible en la máquina local.
A continuación, creemos un script simple que generará alguna salida para que podamos capturarla. Este script:
- Imprimirá información del sistema
- Generará alguna salida estándar
- Generará alguna salida de error estándar
Cree un nuevo archivo en el directorio scripts llamado info.sh:
- Haga clic en el menú "Archivo"
- Seleccione "Nuevo archivo"
- Guárdelo como
scripts/info.shen el directorio~/project/ansible-output-demo
Agregue el siguiente contenido al archivo info.sh:
#!/bin/bash
## Print system information
echo "=== System Information ==="
echo "Hostname: $(hostname)"
echo "Date: $(date)"
echo "Kernel: $(uname -r)"
echo "Memory:"
free -h
## Generate some standard output
echo "=== Standard Output ==="
echo "This is standard output"
echo "Hello from the script!"
## Generate some standard error
echo "=== Standard Error ===" >&2
echo "This is standard error" >&2
echo "An example error message" >&2
## Exit with a specific code
exit 0
Ahora, hagamos que el script sea ejecutable:
chmod +x ~/project/ansible-output-demo/scripts/info.sh
Ejecutemos el script directamente para ver qué salida produce:
~/project/ansible-output-demo/scripts/info.sh
Debería ver una salida que contenga información del sistema, mensajes de salida estándar y mensajes de error estándar.
Ahora tenemos nuestro entorno básico configurado. En el siguiente paso, crearemos un playbook de Ansible para ejecutar este script y capturar su salida.
Captura Básica de Salida con Ansible
Ahora que hemos configurado nuestro entorno, creemos un playbook de Ansible simple que ejecute nuestro script y capture su salida.
Creación de un Playbook Básico
En Ansible, los playbooks son archivos YAML que definen un conjunto de tareas a ejecutar en hosts remotos. Creemos un playbook que ejecute nuestro script info.sh y capture su salida utilizando la palabra clave register.
Cree un nuevo archivo llamado capture_output.yml en el directorio ~/project/ansible-output-demo:
- Haga clic en el menú "Archivo"
- Seleccione "Nuevo archivo"
- Guárdelo como
capture_output.ymlen el directorio~/project/ansible-output-demo
Agregue el siguiente contenido al archivo capture_output.yml:
---
- name: Capture Script Output
hosts: local
gather_facts: no
tasks:
- name: Execute the info.sh script
command: "{{ playbook_dir }}/scripts/info.sh"
register: script_output
- name: Display the script output
debug:
var: script_output.stdout
Examinemos este playbook:
- El playbook se dirige al grupo
localdefinido en nuestro inventario. - La primera tarea ejecuta nuestro script
info.shutilizando el módulocommand. - La palabra clave
registeralmacena la salida del comando en una variable llamadascript_output. - La segunda tarea utiliza el módulo
debugpara mostrar la salida estándar (stdout) del script.
Ejecución del Playbook
Ahora ejecutemos el playbook para ver cómo captura y muestra la salida del script:
cd ~/project/ansible-output-demo
ansible-playbook -i inventory capture_output.yml
Debería ver una salida similar a la siguiente:
PLAY [Capture Script Output] *******************************************
TASK [Execute the info.sh script] **************************************
changed: [localhost]
TASK [Display the script output] ***************************************
ok: [localhost] => {
"script_output.stdout": "=== System Information ===\nHostname: ubuntu\nDate: Tue Oct 17 12:34:56 UTC 2023\nKernel: 5.15.0-1031-aws\nMemory:\n total used free shared buff/cache available\nMem: 7.7Gi 1.2Gi 5.2Gi 12Mi 1.3Gi 6.3Gi\nSwap: 0B 0B 0B\n=== Standard Output ===\nThis is standard output\nHello from the script!"
}
PLAY RECAP ************************************************************
localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Observe que solo se muestra la salida estándar. La salida de error estándar (stderr) no se muestra porque solo pedimos mostrar script_output.stdout.
Mejora de la Legibilidad de la Salida
La salida es un poco difícil de leer como una sola cadena. Modifiquemos nuestro playbook para mostrar la salida en un formato más legible utilizando el atributo stdout_lines, que presenta la salida como una lista de líneas.
Edite el archivo capture_output.yml y modifique la segunda tarea de la siguiente manera:
- name: Display the script output
debug:
var: script_output.stdout_lines
Ejecute el playbook de nuevo:
ansible-playbook -i inventory capture_output.yml
Ahora la salida debería ser más legible, con cada línea mostrada por separado:
TASK [Display the script output] ***************************************
ok: [localhost] => {
"script_output.stdout_lines": [
"=== System Information ===",
"Hostname: ubuntu",
"Date: Tue Oct 17 12:34:56 UTC 2023",
"Kernel: 5.15.0-1031-aws",
"Memory:",
" total used free shared buff/cache available",
"Mem: 7.7Gi 1.2Gi 5.2Gi 12Mi 1.3Gi 6.3Gi",
"Swap: 0B 0B 0B",
"=== Standard Output ===",
"This is standard output",
"Hello from the script!"
]
}
Este formato hace que la salida sea mucho más fácil de leer y trabajar. En el siguiente paso, exploraremos cómo capturar y mostrar diferentes tipos de salida.
Captura de Diferentes Tipos de Salida
En el paso anterior, capturamos y mostramos la salida estándar de nuestro script. Sin embargo, al ejecutar scripts, hay varios tipos de salida que podríamos querer capturar:
- Salida Estándar (stdout): La salida normal del script
- Error Estándar (stderr): Mensajes de error y advertencias
- Código de Retorno (rc): El estado de salida del script (0 normalmente significa éxito, los valores distintos de cero indican errores)
Creemos un nuevo playbook que capture y muestre los tres tipos de salida.
Cree un nuevo archivo llamado capture_all_output.yml en el directorio ~/project/ansible-output-demo:
- Haga clic en el menú "Archivo"
- Seleccione "Nuevo archivo"
- Guárdelo como
capture_all_output.ymlen el directorio~/project/ansible-output-demo
Agregue el siguiente contenido al archivo capture_all_output.yml:
---
- name: Capture All Types of Script Output
hosts: local
gather_facts: no
tasks:
- name: Execute the info.sh script
command: "{{ playbook_dir }}/scripts/info.sh"
register: script_output
- name: Display standard output
debug:
msg: "Standard Output (stdout):"
- name: Display stdout content
debug:
var: script_output.stdout_lines
- name: Display standard error
debug:
msg: "Standard Error (stderr):"
- name: Display stderr content
debug:
var: script_output.stderr_lines
- name: Display return code
debug:
msg: "Return Code: {{ script_output.rc }}"
Este playbook ejecuta nuestro script y luego muestra:
- La salida estándar usando
script_output.stdout_lines - El error estándar usando
script_output.stderr_lines - El código de retorno usando
script_output.rc
Ejecución del Playbook Mejorado
Ejecutemos nuestro nuevo playbook:
cd ~/project/ansible-output-demo
ansible-playbook -i inventory capture_all_output.yml
Debería ver una visualización completa de los tres tipos de salida:
PLAY [Capture All Types of Script Output] *****************************
TASK [Execute the info.sh script] *************************************
changed: [localhost]
TASK [Display standard output] ****************************************
ok: [localhost] => {
"msg": "Standard Output (stdout):"
}
TASK [Display stdout content] *****************************************
ok: [localhost] => {
"script_output.stdout_lines": [
"=== System Information ===",
"Hostname: ubuntu",
"Date: Tue Oct 17 12:40:22 UTC 2023",
"Kernel: 5.15.0-1031-aws",
"Memory:",
" total used free shared buff/cache available",
"Mem: 7.7Gi 1.2Gi 5.2Gi 12Mi 1.3Gi 6.3Gi",
"Swap: 0B 0B 0B",
"=== Standard Output ===",
"This is standard output",
"Hello from the script!"
]
}
TASK [Display standard error] *****************************************
ok: [localhost] => {
"msg": "Standard Error (stderr):"
}
TASK [Display stderr content] *****************************************
ok: [localhost] => {
"script_output.stderr_lines": [
"=== Standard Error ===",
"This is standard error",
"An example error message"
]
}
TASK [Display return code] ********************************************
ok: [localhost] => {
"msg": "Return Code: 0"
}
PLAY RECAP **********************************************************
localhost : ok=6 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Ahora podemos ver todos los tipos de salida de nuestro script:
- La salida estándar muestra información del sistema y nuestros mensajes regulares
- El error estándar muestra nuestros mensajes de error
- El código de retorno es 0, lo que indica una ejecución exitosa
Creación de un Script con Errores
Creemos un script que producirá un error y devolverá un código de salida distinto de cero para ver cómo Ansible lo maneja.
Cree un nuevo archivo llamado error.sh en el directorio scripts:
- Haga clic en el menú "Archivo"
- Seleccione "Nuevo archivo"
- Guárdelo como
scripts/error.shen el directorio~/project/ansible-output-demo
Agregue el siguiente contenido al archivo error.sh:
#!/bin/bash
## Print some standard output
echo "Starting error demonstration script"
echo "This will appear in stdout"
## Print some standard error
echo "This will appear in stderr" >&2
echo "Error: Something went wrong!" >&2
## Exit with a non-zero code to indicate error
exit 1
Haga que el script sea ejecutable:
chmod +x ~/project/ansible-output-demo/scripts/error.sh
Ahora creemos un playbook para ejecutar este script y manejar el error. Cree un nuevo archivo llamado handle_errors.yml:
- Haga clic en el menú "Archivo"
- Seleccione "Nuevo archivo"
- Guárdelo como
handle_errors.ymlen el directorio~/project/ansible-output-demo
Agregue el siguiente contenido al archivo handle_errors.yml:
---
- name: Handle Script Errors
hosts: local
gather_facts: no
tasks:
- name: Execute the error script
command: "{{ playbook_dir }}/scripts/error.sh"
register: script_output
ignore_errors: yes
- name: Display standard output
debug:
var: script_output.stdout_lines
- name: Display standard error
debug:
var: script_output.stderr_lines
- name: Display return code
debug:
msg: "Return Code: {{ script_output.rc }}"
- name: Check if script failed
debug:
msg: "The script failed with return code {{ script_output.rc }}"
when: script_output.rc != 0
Observe la adición de ignore_errors: yes, que le dice a Ansible que continúe ejecutando el playbook incluso si el comando falla (devuelve un código de salida distinto de cero).
Ejecutemos este playbook:
ansible-playbook -i inventory handle_errors.yml
Debería ver una salida similar a la siguiente:
PLAY [Handle Script Errors] *******************************************
TASK [Execute the error script] ***************************************
changed: [localhost]
TASK [Display standard output] ****************************************
ok: [localhost] => {
"script_output.stdout_lines": [
"Starting error demonstration script",
"This will appear in stdout"
]
}
TASK [Display standard error] *****************************************
ok: [localhost] => {
"script_output.stderr_lines": [
"This will appear in stderr",
"Error: Something went wrong!"
]
}
TASK [Display return code] ********************************************
ok: [localhost] => {
"msg": "Return Code: 1"
}
TASK [Check if script failed] *****************************************
ok: [localhost] => {
"msg": "The script failed with return code 1"
}
PLAY RECAP **********************************************************
localhost : ok=5 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Este ejemplo demuestra cómo:
- Capturar la salida de un script que produce un error
- Continuar la ejecución del playbook a pesar del error
- Ejecutar condicionalmente tareas basadas en el código de retorno del script
En el siguiente paso, exploraremos casos de uso más avanzados y las mejores prácticas para trabajar con la salida de scripts en Ansible.
Procesamiento Avanzado de Salida y Casos de Uso Prácticos
Ahora que entendemos cómo capturar diferentes tipos de salida, exploremos algunas técnicas más avanzadas para procesar y utilizar la salida de scripts en Ansible.
Análisis de la Salida con Filtros
Ansible proporciona varios filtros que le permiten manipular y extraer información específica de la salida del script. En esta sección, veremos algunas técnicas comunes de filtrado.
Cree un nuevo archivo llamado parse_output.yml en el directorio ~/project/ansible-output-demo:
- Haga clic en el menú "Archivo"
- Seleccione "Nuevo archivo"
- Guárdelo como
parse_output.ymlen el directorio~/project/ansible-output-demo
Primero, creemos un script que genere una salida estructurada que podamos analizar. Cree un nuevo archivo llamado system_stats.sh:
- Haga clic en el menú "Archivo"
- Seleccione "Nuevo archivo"
- Guárdelo como
scripts/system_stats.shen el directorio~/project/ansible-output-demo
Agregue el siguiente contenido al archivo system_stats.sh:
#!/bin/bash
## Display CPU info
echo "CPU_MODEL: $(grep 'model name' /proc/cpuinfo | head -1 | cut -d ':' -f2 | xargs)"
echo "CPU_CORES: $(grep -c 'processor' /proc/cpuinfo)"
## Display memory info in GB
mem_total=$(free -g | grep Mem | awk '{print $2}')
echo "MEMORY_GB: $mem_total"
## Display disk usage
disk_usage=$(df -h / | tail -1 | awk '{print $5}' | tr -d '%')
echo "DISK_USAGE_PCT: $disk_usage"
## Display load average
load_avg=$(uptime | awk -F'load average: ' '{print $2}' | cut -d, -f1)
echo "LOAD_AVG: $load_avg"
exit 0
Haga que el script sea ejecutable:
chmod +x ~/project/ansible-output-demo/scripts/system_stats.sh
Ahora creemos un playbook que ejecute este script, capture su salida y la analice para extraer información específica:
Agregue el siguiente contenido al archivo parse_output.yml:
---
- name: Parse Script Output
hosts: local
gather_facts: no
tasks:
- name: Execute the system_stats.sh script
command: "{{ playbook_dir }}/scripts/system_stats.sh"
register: stats_output
- name: Display raw output
debug:
var: stats_output.stdout_lines
- name: Parse CPU model
set_fact:
cpu_model: "{{ stats_output.stdout | regex_search('CPU_MODEL: (.+)', '\\1') | first }}"
- name: Parse CPU cores
set_fact:
cpu_cores: "{{ stats_output.stdout | regex_search('CPU_CORES: (\\d+)', '\\1') | first }}"
- name: Parse memory
set_fact:
memory_gb: "{{ stats_output.stdout | regex_search('MEMORY_GB: (\\d+)', '\\1') | first }}"
- name: Parse disk usage
set_fact:
disk_usage: "{{ stats_output.stdout | regex_search('DISK_USAGE_PCT: (\\d+)', '\\1') | first }}"
- name: Parse load average
set_fact:
load_avg: "{{ stats_output.stdout | regex_search('LOAD_AVG: ([0-9.]+)', '\\1') | first }}"
- name: Display parsed information
debug:
msg: |
Parsed system information:
- CPU Model: {{ cpu_model }}
- CPU Cores: {{ cpu_cores }}
- Memory (GB): {{ memory_gb }}
- Disk Usage (%): {{ disk_usage }}
- Load Average: {{ load_avg }}
Este playbook:
- Ejecuta nuestro script
system_stats.sh - Muestra la salida sin procesar
- Utiliza el filtro
regex_searchpara extraer información específica de la salida - Almacena la información extraída en variables
- Muestra la información analizada en un formato estructurado
Ejecutemos este playbook:
cd ~/project/ansible-output-demo
ansible-playbook -i inventory parse_output.yml
Debería ver una salida similar a la siguiente:
PLAY [Parse Script Output] ********************************************
TASK [Execute the system_stats.sh script] *****************************
changed: [localhost]
TASK [Display raw output] *********************************************
ok: [localhost] => {
"stats_output.stdout_lines": [
"CPU_MODEL: Intel(R) Xeon(R) CPU E5-2676 v3 @ 2.40GHz",
"CPU_CORES: 2",
"MEMORY_GB: 7",
"DISK_USAGE_PCT: 58",
"LOAD_AVG: 0.08"
]
}
TASK [Parse CPU model] ************************************************
ok: [localhost]
TASK [Parse CPU cores] ************************************************
ok: [localhost]
TASK [Parse memory] ***************************************************
ok: [localhost]
TASK [Parse disk usage] ***********************************************
ok: [localhost]
TASK [Parse load average] *********************************************
ok: [localhost]
TASK [Display parsed information] *************************************
ok: [localhost] => {
"msg": "Parsed system information:\n- CPU Model: Intel(R) Xeon(R) CPU E5-2676 v3 @ 2.40GHz\n- CPU Cores: 2\n- Memory (GB): 7\n- Disk Usage (%): 58\n- Load Average: 0.08"
}
PLAY RECAP ***********************************************************
localhost : ok=8 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Tomar Decisiones Basadas en la Salida
Uno de los aspectos más poderosos de la captura de la salida del script es usarla para tomar decisiones en sus playbooks de Ansible. Creemos un playbook que demuestre la ejecución condicional basada en la salida del script.
Cree un nuevo archivo llamado conditional_actions.yml en el directorio ~/project/ansible-output-demo:
- Haga clic en el menú "Archivo"
- Seleccione "Nuevo archivo"
- Guárdelo como
conditional_actions.ymlen el directorio~/project/ansible-output-demo
Agregue el siguiente contenido:
---
- name: Conditional Actions Based on Script Output
hosts: local
gather_facts: no
tasks:
- name: Execute the system_stats.sh script
command: "{{ playbook_dir }}/scripts/system_stats.sh"
register: stats_output
- name: Parse disk usage
set_fact:
disk_usage: "{{ stats_output.stdout | regex_search('DISK_USAGE_PCT: (\\d+)', '\\1') | first | int }}"
- name: Parse load average
set_fact:
load_avg: "{{ stats_output.stdout | regex_search('LOAD_AVG: ([0-9.]+)', '\\1') | first | float }}"
- name: Display system status
debug:
msg: "Current system status: Disk usage: {{ disk_usage }}%, Load average: {{ load_avg }}"
- name: Warn about high disk usage
debug:
msg: "WARNING: Disk usage is high at {{ disk_usage }}%. Consider cleaning up disk space."
when: disk_usage > 50
- name: Warn about high load average
debug:
msg: "WARNING: Load average is high at {{ load_avg }}. Check for resource-intensive processes."
when: load_avg > 1.0
- name: Report healthy system
debug:
msg: "System is healthy. All metrics within normal ranges."
when: disk_usage <= 50 and load_avg <= 1.0
Este playbook:
- Ejecuta el script
system_stats.sh - Analiza los valores de uso del disco y promedio de carga
- Muestra diferentes mensajes basados en los valores:
- Una advertencia si el uso del disco es superior al 50%
- Una advertencia si el promedio de carga es superior a 1.0
- Un mensaje de "sistema saludable" si todas las métricas están dentro de los rangos normales
Ejecutemos este playbook:
ansible-playbook -i inventory conditional_actions.yml
La salida dependerá del estado actual de su sistema, pero debería incluir mensajes condicionales basados en el uso de su disco y el promedio de carga.
Estos ejemplos demuestran cómo puede:
- Analizar y extraer información específica de la salida del script
- Usar esa información para tomar decisiones en sus playbooks de Ansible
- Tomar diferentes acciones basadas en la salida del script
Estas técnicas son esenciales para crear flujos de trabajo de automatización dinámicos y receptivos que pueden adaptarse a diferentes condiciones y escenarios.
Caso de Uso del Mundo Real - Verificación del Estado del Sistema
En este paso final, crearemos un ejemplo completo del mundo real que reúne todo lo que hemos aprendido sobre la captura y el procesamiento de la salida de scripts con Ansible. Construiremos una herramienta de verificación del estado del sistema que:
- Recopila varias métricas del sistema
- Analiza las métricas para identificar posibles problemas
- Genera un informe de estado
- Toma medidas correctivas cuando sea necesario
Creación del Script de Verificación del Estado
Primero, creemos un script completo de verificación del estado que recopile varias métricas del sistema.
Cree un nuevo archivo llamado health_check.sh en el directorio scripts:
- Haga clic en el menú "Archivo"
- Seleccione "Nuevo archivo"
- Guárdelo como
scripts/health_check.shen el directorio~/project/ansible-output-demo
Agregue el siguiente contenido al archivo health_check.sh:
#!/bin/bash
## System Health Check Script
echo "HEALTH_CHECK_START: $(date)"
## CPU load
cpu_load=$(uptime | awk -F'load average: ' '{print $2}' | cut -d, -f1)
echo "CPU_LOAD: $cpu_load"
if (($(echo "$cpu_load > 1.0" | bc -l))); then
echo "CPU_STATUS: WARNING"
else
echo "CPU_STATUS: OK"
fi
## Memory usage
mem_total=$(free | grep Mem | awk '{print $2}')
mem_used=$(free | grep Mem | awk '{print $3}')
mem_pct=$(echo "scale=2; $mem_used / $mem_total * 100" | bc)
echo "MEM_USAGE_PCT: $mem_pct"
if (($(echo "$mem_pct > 80" | bc -l))); then
echo "MEM_STATUS: WARNING"
else
echo "MEM_STATUS: OK"
fi
## Disk usage
disk_usage=$(df -h / | tail -1 | awk '{print $5}' | tr -d '%')
echo "DISK_USAGE_PCT: $disk_usage"
if [ "$disk_usage" -gt 80 ]; then
echo "DISK_STATUS: WARNING"
else
echo "DISK_STATUS: OK"
fi
## Check for zombie processes
zombie_count=$(ps aux | grep -c Z)
echo "ZOMBIE_PROCESSES: $zombie_count"
if [ "$zombie_count" -gt 0 ]; then
echo "ZOMBIE_STATUS: WARNING"
else
echo "ZOMBIE_STATUS: OK"
fi
## Check system uptime
uptime_days=$(uptime | awk '{print $3}')
echo "UPTIME_DAYS: $uptime_days"
## Check last 5 log entries for errors
echo "RECENT_ERRORS: $(grep -i error /var/log/syslog 2> /dev/null | tail -5 | wc -l)"
echo "HEALTH_CHECK_END: $(date)"
Haga que el script sea ejecutable:
chmod +x ~/project/ansible-output-demo/scripts/health_check.sh
Creación del Playbook de Verificación del Estado
Ahora, creemos un playbook completo que ejecute el script de verificación del estado, analice los resultados y tome las acciones apropiadas en función de los hallazgos.
Cree un nuevo archivo llamado system_health_check.yml en el directorio ~/project/ansible-output-demo:
- Haga clic en el menú "Archivo"
- Seleccione "Nuevo archivo"
- Guárdelo como
system_health_check.ymlen el directorio~/project/ansible-output-demo
Agregue el siguiente contenido al archivo system_health_check.yml:
---
- name: System Health Check
hosts: local
gather_facts: no
tasks:
- name: Execute health check script
command: "{{ playbook_dir }}/scripts/health_check.sh"
register: health_check
- name: Display raw health check output
debug:
var: health_check.stdout_lines
## Parse metrics from the health check output
- name: Parse CPU load
set_fact:
cpu_load: "{{ health_check.stdout | regex_search('CPU_LOAD: ([0-9.]+)', '\\1') | first | float }}"
cpu_status: "{{ health_check.stdout | regex_search('CPU_STATUS: (\\w+)', '\\1') | first }}"
- name: Parse memory usage
set_fact:
mem_usage: "{{ health_check.stdout | regex_search('MEM_USAGE_PCT: ([0-9.]+)', '\\1') | first | float }}"
mem_status: "{{ health_check.stdout | regex_search('MEM_STATUS: (\\w+)', '\\1') | first }}"
- name: Parse disk usage
set_fact:
disk_usage: "{{ health_check.stdout | regex_search('DISK_USAGE_PCT: (\\d+)', '\\1') | first | int }}"
disk_status: "{{ health_check.stdout | regex_search('DISK_STATUS: (\\w+)', '\\1') | first }}"
- name: Parse zombie processes
set_fact:
zombie_count: "{{ health_check.stdout | regex_search('ZOMBIE_PROCESSES: (\\d+)', '\\1') | first | int }}"
zombie_status: "{{ health_check.stdout | regex_search('ZOMBIE_STATUS: (\\w+)', '\\1') | first }}"
## Generate a health status summary
- name: Generate health status summary
set_fact:
health_status:
cpu:
load: "{{ cpu_load }}"
status: "{{ cpu_status }}"
memory:
usage_percent: "{{ mem_usage }}"
status: "{{ mem_status }}"
disk:
usage_percent: "{{ disk_usage }}"
status: "{{ disk_status }}"
processes:
zombie_count: "{{ zombie_count }}"
status: "{{ zombie_status }}"
## Display health summary
- name: Display health summary
debug:
var: health_status
## Check overall system status
- name: Determine overall system status
set_fact:
overall_status: "{{ 'WARNING' if (cpu_status == 'WARNING' or mem_status == 'WARNING' or disk_status == 'WARNING' or zombie_status == 'WARNING') else 'OK' }}"
- name: Display overall system status
debug:
msg: "Overall System Status: {{ overall_status }}"
## Take remedial actions if necessary
- name: Recommend actions for CPU issues
debug:
msg: "Action recommended: Check for resource-intensive processes using 'top' or 'htop'"
when: cpu_status == "WARNING"
- name: Recommend actions for memory issues
debug:
msg: "Action recommended: Free up memory by restarting services or clearing cache"
when: mem_status == "WARNING"
- name: Recommend actions for disk issues
debug:
msg: "Action recommended: Clean up disk space using 'du -sh /* | sort -hr' to identify large directories"
when: disk_status == "WARNING"
- name: Recommend actions for zombie processes
debug:
msg: "Action recommended: Identify and restart parent processes of zombies"
when: zombie_status == "WARNING"
## Generate health report file
- name: Create health report directory
file:
path: "{{ playbook_dir }}/reports"
state: directory
- name: Get current timestamp
command: date "+%Y%m%d_%H%M%S"
register: timestamp
- name: Create health report file
copy:
content: |
System Health Report - {{ timestamp.stdout }}
----------------------------------------------
CPU:
Load Average: {{ cpu_load }}
Status: {{ cpu_status }}
Memory:
Usage: {{ mem_usage }}%
Status: {{ mem_status }}
Disk:
Usage: {{ disk_usage }}%
Status: {{ disk_status }}
Processes:
Zombie Count: {{ zombie_count }}
Status: {{ zombie_status }}
Overall Status: {{ overall_status }}
Recommendations:
{% if cpu_status == "WARNING" %}
- CPU: Check for resource-intensive processes using 'top' or 'htop'
{% endif %}
{% if mem_status == "WARNING" %}
- Memory: Free up memory by restarting services or clearing cache
{% endif %}
{% if disk_status == "WARNING" %}
- Disk: Clean up disk space using 'du -sh /* | sort -hr' to identify large directories
{% endif %}
{% if zombie_status == "WARNING" %}
- Processes: Identify and restart parent processes of zombies
{% endif %}
{% if overall_status == "OK" %}
- System is healthy. No actions required.
{% endif %}
dest: "{{ playbook_dir }}/reports/health_report_{{ timestamp.stdout }}.txt"
- name: Display report location
debug:
msg: "Health report saved to {{ playbook_dir }}/reports/health_report_{{ timestamp.stdout }}.txt"
Este playbook completo:
- Ejecuta nuestro script de verificación del estado
- Analiza las diversas métricas de la salida del script
- Crea un resumen estructurado del estado del sistema
- Determina el estado general del sistema en función de los estados de los componentes individuales
- Proporciona recomendaciones específicas para cualquier problema detectado
- Genera un archivo de informe de estado detallado con marca de tiempo
Ejecución de la Verificación del Estado
Ejecutemos nuestro playbook de verificación del estado del sistema:
cd ~/project/ansible-output-demo
ansible-playbook -i inventory system_health_check.yml
Debería ver una salida detallada que muestra el estado del sistema, junto con cualquier recomendación necesaria para mejorar. La salida variará según el estado actual de su sistema.
Después de ejecutar el playbook, verifique el directorio de informes para ver el informe de estado generado:
ls -l ~/project/ansible-output-demo/reports/
Debería ver un archivo llamado health_report_[timestamp].txt. Vea el contenido de este archivo:
cat ~/project/ansible-output-demo/reports/health_report_*.txt
Resumen de lo que Aprendimos
A lo largo de este tutorial, hemos aprendido:
- Cómo capturar diferentes tipos de salida (stdout, stderr, códigos de retorno) de scripts ejecutados por Ansible
- Cómo analizar y extraer información específica de la salida del script utilizando filtros de Ansible
- Cómo usar la salida del script para tomar decisiones y realizar acciones condicionales
- Cómo implementar una solución completa del mundo real que aprovecha la salida del script para la supervisión del estado del sistema
Estas técnicas son herramientas poderosas en su conjunto de herramientas de automatización de Ansible, lo que le permite crear flujos de trabajo de automatización sofisticados, dinámicos y receptivos.
Resumen
En este laboratorio, exploramos cómo capturar y utilizar eficazmente la salida de scripts ejecutados a través de Ansible. Comenzamos con la captura básica de salida utilizando la palabra clave register y avanzamos a técnicas más avanzadas, como el análisis de la salida con filtros y la toma de decisiones basadas en los resultados del script.
Las conclusiones clave de este tutorial incluyen:
- La capacidad de capturar diferentes tipos de salida (stdout, stderr, códigos de retorno) de scripts ejecutados por Ansible
- Técnicas para analizar y extraer información específica de la salida del script
- Métodos para ejecutar tareas condicionalmente en función de la salida del script
- Un ejemplo completo del mundo real que demuestra cómo construir una solución de monitoreo del estado del sistema con Ansible
Al dominar estas técnicas, puede crear flujos de trabajo de automatización más sofisticados, dinámicos y receptivos que pueden adaptarse a diferentes condiciones y escenarios. Esta capacidad es esencial para la gestión eficaz de la infraestructura, la implementación de aplicaciones y la administración del sistema utilizando Ansible.
A medida que continúe su viaje con Ansible, recuerde que la captura de la salida del script es solo una de las muchas funciones poderosas que ofrece Ansible. Explorar otras capacidades de Ansible, como roles, plantillas y vault, mejorará aún más su conjunto de herramientas de automatización.


