¿Te resulta más fácil leer con fondo crema, un tono de color, más contraste o un texto más grande? Elige tus colores y tu texto una sola vez, para todas las páginas.

Lección gratuita

Idempotencia y deriva

Después de esta lección: Puedo ejecutar un playbook dos veces y decir qué cambió y por qué.

Lección de 60 min10 comandosLaboratorio de Ansible: configurar una máquina con un playbook, en el navegador

El servidor que alguien arregló a mano

A las dos de la madrugada el cartel de una tienda dice Cerrado toda la semana cuando debería decir Abierto de 9 a 17. Alguien editó el archivo en el servidor en producción y no avisó a nadie.

La próxima vez que corra el playbook debería notarlo y devolver el archivo a su sitio. Esta lección muestra cómo, y cómo mirar primero sin cambiar nada.

Al final de esta lección

Nota

Puedo ejecutar un playbook dos veces y decir qué cambió y por qué.

Palabras clave

PalabraQué significaEjemplo
Idempotentevolver a ejecutarlo ya no cambia nada
Derivalo real ya no coincide con su descripción
Modo checkuna ejecución que informa de cambios sin hacerlos--check
Difflas líneas que cambiarían--diff
Recaplos totales que se imprimen al final de una ejecuciónPLAY RECAP

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Un playbook describe el final, no los pasos

Una tarea dice cómo debe estar un archivo, no qué escribir. Si el archivo ya está bien, la tarea no hace nada e informa ok. Si no, lo arregla e informa changed.

Por eso un buen playbook es idempotente: la segunda ejecución no informa de cambios.

Crea una carpeta y entra

Comando
mkdir -p ~/iac-demo/drift && cd ~/iac-demo/drift

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Escribe un playbook con una tarea

Comando
printf '%s\n' '- hosts: localhost' '  connection: local' '  gather_facts: false' '  vars:' '    hours: "Abierto de 9 a 17"' '  tasks:' '    - name: escribir el aviso' '      ansible.builtin.copy:' '        dest: ./notice.txt' '        content: "{{ hours }}\n"' '        mode: "0644"' > site.yml

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Ejecútalo la primera vez

Comando
ansible-playbook -i localhost, site.yml | grep -E "changed="

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Ejecútalo otra vez

Comando
ansible-playbook -i localhost, site.yml | grep -E "changed="

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

La deriva es un cambio que nadie anotó

La deriva es cuando lo real deja de coincidir con la descripción, a menudo porque alguien lo cambió a mano. La idempotencia hace fácil reparar la deriva.

Ejecuta primero el playbook en modo check. Informa de lo que cambiaría, --diff muestra las líneas, pero no se escribe nada.

Edita el archivo a mano

Comando
echo "Cerrado toda la semana" > notice.txt; cat notice.txt

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Mira primero con check y diff

Comando
ansible-playbook -i localhost, site.yml --check --diff | grep -E "^[-+][^-+]|changed="

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Lee el archivo otra vez

Comando
cat notice.txt

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Ejecútalo de verdad y luego otra vez

Comando
ansible-playbook -i localhost, site.yml | grep -E "changed="; cat notice.txt; ansible-playbook -i localhost, site.yml | grep -E "changed="

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Una tarea shell no ve el cambio

El módulo copy compara el archivo con lo deseado. El módulo shell solo ejecuta un comando y no puede saber si algo cambió. Informa changed siempre.

El lab de Ansible rechaza un playbook hecho solo de comandos shell por este motivo.

Escribe el mismo trabajo como comando shell

Comando
printf '%s\n' '- hosts: localhost' '  connection: local' '  gather_facts: false' '  tasks:' '    - name: escribir con un shell' '      ansible.builtin.shell: echo "Abierto de 9 a 17" > ./shell.txt' > shell.yml

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Ejecútalo dos veces

Comando
ansible-playbook -i localhost, shell.yml | grep -E "changed="; ansible-playbook -i localhost, shell.yml | grep -E "changed="

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Un error frecuente

Advertencia

Mucha gente cree que changed=0 en la primera ejecución significa que el playbook no hizo nada útil. Significa que la máquina ya coincidía con lo deseado. Una ejecución que siempre dice changed oculta la deriva, porque un cambio real se ve igual que uno normal.

OpenTofu halla la deriva refrescando el estado

Con un provider real, tofu plan pregunta primero al servicio real qué existe y muestra la diferencia con el estado. Así nota un cambio a mano.

El terraform_data del lab guarda un valor y nada fuera de OpenTofu, así que no hay nada que cambiar a mano. Esta lección usa un archivo.

Una convergencia calculada en Python

Código: python
# Lleva una máquina al estado deseado y cuenta lo que cambió.
wish = {"hours": "Abierto de 9 a 17", "phone": "0100"}
machine = {"hours": "Cerrado", "extra": "no me toques"}
changed = 0
for name in wish:
    if name not in machine or machine[name] != wish[name]:
        machine[name] = wish[name]
        changed = changed + 1
print("changed =", changed)
# Ejecuta el bucle otra vez y mira changed.

Para ir más lejos: cambia lo deseado

Ejecuta ansible-playbook -i localhost, site.yml -e '{"hours": "Abierto de 10 a 16"}' | grep -E "changed=" y luego cat notice.txt. Ejecuta el mismo comando otra vez.

¿Por qué la primera ejecución cambia el archivo y la segunda no, y qué variable ganó?

Sobre este laboratorio y su código: Laboratorio de Ansible: configurar una máquina con un playbook, en el navegador

¿Enseñas a una clase? Asigna este módulo a tus alumnos con guía del profesor, tareas con corrección automática y un laboratorio para cada alumno.