Introducción
Los bloques (blocks) de Ansible permiten agrupar tareas relacionadas. Una sección rescue se ejecuta cuando una tarea dentro del bloque falla, mientras que una sección always se ejecuta en cualquier caso, independientemente de si hubo éxito o fallo.
En este laboratorio, creará un fallo controlado, se recuperará de él y luego volverá a ejecutar el mismo playbook con el fallo desactivado para observar la ruta de éxito.
Crear un proyecto de manejo de fallos
En este paso, creará un pequeño proyecto con un host gestionado local y un directorio de informes para los marcadores de block, rescue y always.
cd /home/labex/project
mkdir -p rhce-ansible/{inventory,playbooks,reports}
cd rhce-ansible
cat > ansible.cfg <<'EOF'
[defaults]
inventory = ./inventory/hosts
host_key_checking = False
retry_files_enabled = False
EOF
cat > inventory/hosts <<'EOF'
[managed]
host ansible_connection=local
EOF
El directorio reports es donde el playbook escribirá marcadores para cada ruta. Esto hace que el comportamiento del bloque sea visible sin depender únicamente de la salida de la terminal.
Escribir un bloque con rescue y always
En este paso, escribirá un playbook con un fallo controlado. El bloque fallará cuando simulate_failure sea verdadero, la sección rescue escribirá un marcador de recuperación y la sección always escribirá un marcador de auditoría.
Antes de ejecutar los comandos en este paso, regrese al directorio del proyecto de Ansible. Esto mantiene la estabilidad de los comandos incluso si LabEx ejecuta cada paso por separado.
cd /home/labex/project/rhce-ansible
cat > playbooks/block-rescue.yml <<'EOF'
---
- name: Practice block rescue and always
hosts: managed
gather_facts: false
vars:
simulate_failure: true
tasks:
- name: Remove old markers
ansible.builtin.file:
path: "/home/labex/project/rhce-ansible/reports/{{ item }}.txt"
state: absent
loop:
- block-success
- rescued
- always
- name: Protect a risky operation with rescue
block:
- name: Run a command that may fail
ansible.builtin.command: /usr/bin/false
when: simulate_failure | bool
- name: Mark block success
ansible.builtin.copy:
dest: /home/labex/project/rhce-ansible/reports/block-success.txt
content: |
block completed
mode: '0644'
rescue:
- name: Mark rescue path
ansible.builtin.copy:
dest: /home/labex/project/rhce-ansible/reports/rescued.txt
content: |
rescued controlled failure
mode: '0644'
always:
- name: Mark always path
ansible.builtin.copy:
dest: /home/labex/project/rhce-ansible/reports/always.txt
content: |
always ran
mode: '0644'
EOF
El comando de riesgo es /usr/bin/false, el cual siempre termina con un fallo. Cuando simulate_failure es verdadero, el bloque se detiene en esa tarea fallida, la sección rescue escribe rescued.txt y la sección always escribe always.txt en cualquier caso.
ansible-playbook playbooks/block-rescue.yml --syntax-check
Las palabras clave block, rescue y always deben estar alineadas al mismo nivel de sangría. Una verificación de sintaxis es una forma rápida de detectar una sección mal colocada antes de ejecutar el fallo controlado.
Ejecutar la ruta de fallo controlado
En este paso, ejecutará el playbook con el fallo predeterminado habilitado. El resumen del play debería mostrar una tarea rescatada en lugar de un play fallido. Antes de ejecutar los comandos en este paso, regrese al directorio del proyecto de Ansible.
cd /home/labex/project/rhce-ansible
ansible-playbook playbooks/block-rescue.yml | tee reports/failure-path.txt
Se espera que esta ejecución muestre rescued=1 y failed=0 en el resumen. Esto significa que Ansible detectó un fallo en una tarea dentro del bloque, ejecutó las tareas de rescate y no consideró el play general como fallido.
cat reports/rescued.txt reports/always.txt
Los dos archivos de marcador deberían decir rescued controlled failure y always ran. No debería ver block-success.txt en esta ruta porque el bloque no llegó a la tarea del marcador de éxito.
Ejecutar la ruta de éxito con una variable adicional
En este paso, anulará simulate_failure desde la línea de comandos. El bloque debería completarse normalmente, el rescate no debería ejecutarse y la sección always debería ejecutarse de todos modos.
Antes de ejecutar los comandos en este paso, regrese al directorio del proyecto de Ansible.
cd /home/labex/project/rhce-ansible
ansible-playbook playbooks/block-rescue.yml -e simulate_failure=false | tee reports/success-path.txt
La opción -e simulate_failure=false anula la variable del playbook solo para esta ejecución. Ahora, el comando false se omite, el bloque normal llega a block-success.txt y la sección de rescate no debería ejecutarse.
cat reports/block-success.txt reports/always.txt
La ruta de éxito debería mostrar block completed y always ran. El playbook elimina los marcadores antiguos al inicio, por lo que rescued.txt ya no debería existir después de esta ejecución.
Comparar la evidencia de fallo y éxito
En este paso, comparará las dos ejecuciones guardadas del playbook. Mantener la evidencia pequeña le ayuda a solucionar problemas sobre qué ruta se ejecutó sin tener que leer toda la salida. Antes de ejecutar los comandos en este paso, regrese al directorio del proyecto de Ansible.
cd /home/labex/project/rhce-ansible
grep -E 'rescued=|failed=' reports/failure-path.txt reports/success-path.txt
El informe de la ruta de fallo debería contener rescued=1, mientras que el informe de la ruta de éxito debería contener rescued=0. Ambos deberían tener failed=0, pero por razones diferentes.
ls -1 reports
La lista de informes debería incluir ambas salidas guardadas del playbook, además de los marcadores de la ruta más reciente. Mantener ambas salidas facilita la comparación de cómo el rescate cambia el resumen.
Resumen
Ha utilizado las secciones block, rescue y always para manejar un fallo controlado, luego ejecutó el mismo playbook a través de una ruta de éxito normal y comparó la evidencia guardada.


