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
| Palabra | Qué significa | Ejemplo |
|---|---|---|
| Idempotente | volver a ejecutarlo ya no cambia nada | |
| Deriva | lo real ya no coincide con su descripción | |
| Modo check | una ejecución que informa de cambios sin hacerlos | --check |
| Diff | las líneas que cambiarían | --diff |
| Recap | los totales que se imprimen al final de una ejecución | PLAY 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
mkdir -p ~/iac-demo/drift && cd ~/iac-demo/driftSe 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
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.ymlSe 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
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
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
echo "Cerrado toda la semana" > notice.txt; cat notice.txtSe 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
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
cat notice.txtSe 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
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
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.ymlSe 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
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
# 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ó?