Introducción
Un playbook puede seleccionar trabajos distintos para cada host sin duplicar toda la lista de tareas. Combinarás entradas booleanas de políticas con datos recopilados del sistema operativo, procesarás cada elemento de una lista estructurada y usarás resultados reales registrados de inspección para una decisión independiente de aprobación. Los archivos reales y la limpieza explícita harán observable tanto el comportamiento seleccionado como el omitido.
Seleccionar tareas con entradas booleanas y datos recopilados
En este paso, harás que un playbook reutilizable actúe de forma distinta en los dos hosts y elimine explícitamente las salidas cuando se desactive la política.
El entorno preparado tiene una entrada de aprobación separada en /home/automation/maintenance-approved únicamente en web1. Deja esa entrada sin cambios por ahora; la primera decisión de política usa en su lugar una variable booleana y datos descubiertos del sistema operativo.
Entra en el proyecto del controlador:
cd /home/labex/project
Los archivos de variables de host asocian datos con cada nombre del inventario. Escribe valores booleanos YAML sin comillas para que sigan siendo valores true/false en lugar de cadenas:
cat > host_vars/web1.yml <<'YAML'
maintenance_enabled: true
YAML
cat > host_vars/web2.yml <<'YAML'
maintenance_enabled: false
YAML
La palabra clave when evalúa una expresión booleana para el host actual. No encierres la expresión entre llaves Jinja. Aquí and exige tanto una política activada como datos de la familia Debian. not invierte un booleano y or permite que cualquiera de las dos razones seleccione la rama de limpieza.
cat > maintenance.yml <<'YAML'
- name: Apply a host-specific maintenance policy
hosts: all
gather_facts: true
tasks:
- name: Prepare the common policy directory
ansible.builtin.file:
path: /home/automation/maintenance-policy
state: directory
mode: "0750"
- name: Record enabled Debian maintenance
ansible.builtin.copy:
dest: /home/automation/maintenance-policy/enabled.txt
content: "Enabled maintenance\n"
mode: "0640"
when: maintenance_enabled and ansible_facts.os_family == "Debian"
- name: Remove the marker when the policy is disabled
ansible.builtin.file:
path: /home/automation/maintenance-policy/enabled.txt
state: absent
when: not maintenance_enabled or ansible_facts.os_family != "Debian"
YAML
El directorio común existe en ambos hosts. Solo los hosts Debian con la política activada reciben el marcador; la tarea absent complementaria lo elimina cuando se desactiva la política. Una tarea de creación omitida por sí sola dejaría un marcador antiguo, por lo que la limpieza es una tarea separada de estado deseado.
Valida y aplica la política:
ansible-playbook maintenance.yml --syntax-check
ansible-playbook maintenance.yml
La salida debería mostrar decisiones distintas de changed/ok/skipped para web1 y web2. Inspecciona los metadatos reales del marcador en ambos hosts:
ansible all -m ansible.builtin.stat -a 'path=/home/automation/maintenance-policy/enabled.txt'
Stat debería informar exists true en web1 y false en web2. Para ejercitar la limpieza, sobrescribe el booleano para ambos hosts. Las variables extra JSON conservan el tipo booleano false; las comillas simples exteriores protegen el JSON de la interpretación de la shell:
ansible-playbook maintenance.yml -e '{"maintenance_enabled":false}'
ansible all -m ansible.builtin.stat -a 'path=/home/automation/maintenance-policy/enabled.txt'
Ambos marcadores deberían estar ahora ausentes. Restablece la política guardada de cada host ejecutando sin el valor temporal que la sobrescribe:
ansible-playbook maintenance.yml
Web1 debería recuperar el marcador mientras web2 permanece desactivado. El valor temporal no editó los archivos guardados de variables de host.
Aplicar cada elemento de un bucle estructurado
En este paso, producirás un registro real de comprobación de mantenimiento para cada elemento declarado en el host con la política activada.
Una lista YAML contiene varias entradas introducidas con un guion. Cada entrada siguiente es un mapa con campos name y purpose. Las variables de grupo para all hacen que esta lista esté disponible para ambos hosts, mientras que la condición booleana existente sigue decidiendo qué host recibe salidas.
cat > group_vars/all.yml <<'YAML'
maintenance_checks:
- name: disk
purpose: Inspect disk space
- name: logs
purpose: Inspect application logs
- name: packages
purpose: Inspect package state
YAML
loop repite una tarea para cada entrada de la lista. Dentro de una iteración, item.name e item.purpose leen los campos de esa entrada. La condición when se evalúa para cada host y elemento. Añade estas tareas al playbook existente, manteniendo la sangría alineada con las tareas anteriores:
cat >> maintenance.yml <<'YAML'
- name: Prepare checks only for enabled Debian hosts
ansible.builtin.file:
path: /home/automation/maintenance-policy/checks
state: directory
mode: "0750"
when: maintenance_enabled and ansible_facts.os_family == "Debian"
- name: Write every declared maintenance check
ansible.builtin.copy:
dest: "/home/automation/maintenance-policy/checks/{{ item.name }}.txt"
content: |
host={{ inventory_hostname }}
check={{ item.name }}
purpose={{ item.purpose }}
mode: "0640"
loop: "{{ maintenance_checks }}"
when: maintenance_enabled and ansible_facts.os_family == "Debian"
- name: Remove check outputs when the policy is disabled
ansible.builtin.file:
path: /home/automation/maintenance-policy/checks
state: absent
when: not maintenance_enabled or ansible_facts.os_family != "Debian"
YAML
La tarea de limpieza elimina todo el directorio de comprobaciones en los hosts desactivados, incluidas las salidas antiguas de una política activada anteriormente. El bucle escribe contenido estable y permisos explícitos en los hosts activados.
Aplica el playbook ampliado:
ansible-playbook maintenance.yml
Web1 debería tener tres resultados del bucle, uno por comprobación. Web2 debería omitir esas escrituras y no conservar ningún directorio checks. Lee los tres artefactos reales de web1 en lugar de considerar un elemento correcto como prueba de toda la lista:
ansible web1 -m ansible.builtin.command -a 'cat /home/automation/maintenance-policy/checks/disk.txt /home/automation/maintenance-policy/checks/logs.txt /home/automation/maintenance-policy/checks/packages.txt'
La salida debería identificar host=web1 para cada registro y mostrar el nombre y propósito de comprobación correspondientes. Inspecciona el host desactivado de forma independiente:
ansible web2 -m ansible.builtin.stat -a 'path=/home/automation/maintenance-policy/checks'
Su resultado stat debería informar exists false. Estos registros declaran instrucciones de comprobación de mantenimiento; no pretenden ejecutar por sí mismos las inspecciones de disco, registros o paquetes.
Crear ramas según un resultado registrado de inspección
En este paso, usarás un resultado real de stat como entrada independiente de decisión y confirmarás que la política completa es estable al repetirla.
La entrada de aprobación es independiente de maintenance_enabled. Una tarea stat siempre inspecciona cada host y después register guarda el resultado de ese host. Su booleano stat.exists distingue de forma segura una entrada existente de una ruta ausente. Añade la inspección y las tareas complementarias de salida:
cat >> maintenance.yml <<'YAML'
- name: Inspect the independent approval input
ansible.builtin.stat:
path: /home/automation/maintenance-approved
register: approval_info
- name: Record an existing approval input
ansible.builtin.copy:
dest: /home/automation/maintenance-policy/approved.txt
content: "Approval input exists\n"
mode: "0640"
when: approval_info.stat.exists
- name: Remove the output when approval input is absent
ansible.builtin.file:
path: /home/automation/maintenance-policy/approved.txt
state: absent
when: not approval_info.stat.exists
YAML
La tarea copy consume el valor exists registrado. La tarea absent cubre su opuesto para que eliminar una entrada de aprobación también elimine la salida de aprobación obsoleta. Esta rama se basa en el estado inspeccionado en lugar de un mensaje debug fijo.
Ejecuta la política completa:
ansible-playbook maintenance.yml
La entrada preparada de aprobación existe únicamente en web1, por lo que solo web1 debería tener approved.txt. Inspecciona ambas rutas reales de salida:
ansible all -m ansible.builtin.stat -a 'path=/home/automation/maintenance-policy/approved.txt'
Web1 debería informar exists true y web2 false. Repite el playbook:
ansible-playbook maintenance.yml
Ambas filas del resumen deberían informar changed=0, failed=0 y unreachable=0. Las tareas omitidas son esperadas cuando una condición es falsa; cada elemento requerido del bucle y cada salida seleccionada deben seguir existiendo con el contenido correcto.
Resumen
Has usado datos booleanos por host y datos descubiertos para seleccionar tareas, procesado cada mapa de un bucle y creado ramas según metadatos de stat registrados. Las tareas absent complementarias eliminaron salidas obsoletas en lugar de suponer que una creación omitida deshace el estado anterior. Ambos hosts convergieron a los resultados distintos de sus políticas sin cambios repetidos innecesarios.



