Uno de los principales propósitos por los que la humanidad creó a las máquinas, y a los sistemas computacionales en general, fue para evitar hacer tareas simples y repetitivas que consumen tiempo; tiempo que puede ser invertido en otras tareas que requieren de un pensamiento complejo que solo un humano podría realizar.

Lo divertido es que dichas máquinas y dichos sistemas computacionales han traído sus propias tareas simples y repetitivas; de cierta manera, solo hemos cambiado una tarea repetitiva por otra. Tareas como el mantenimiento de una máquina grande, la actualización de software o incluso limpiar los archivos de tu smartphone son tareas repetitivas del siglo XXI. Para estas tareas repetitivas también hemos desarrollado máquinas y sistemas que nos ayudan a ahorrar tiempo. Hay máquinas que limpian y arreglan otras máquinas de manera autónoma, casi todas las actualizaciones de software se instalan automáticamente y hay apps que borran cada cierto tiempo los archivos de tu smartphone que no se usan.

El trabajo en desarrollo web está lleno de tareas repetitivas que, sorprendentemente, muchas personas aún hacen manualmente. En algunas empresas, incluso tienen a una persona cuya labor es hacer lo mismo una y otra vez. Tareas como actualizar el código en el servidor después de finalizado un sprint, instalar o actualizar paquetes de sistema, configurar servicios como apache o nginx o incluso borrar instancias inutilizadas, son tareas que son muy similares cada vez que se ejecutan, así que pueden ser automatizadas; pero no lo son.

Aquí es donde aparece ansible. De acuerdo a su documentación

Ansible es una herramienta de automatización de TI. Puede configurar sistemas, implementar software,  organizar tareas de TI más avanzadas, como implementaciones continuas o actualizaciones de tiempo de inactividad cero.

Para usar ansible, solo necesitas tener instalado python en tu servidor (ansible es un paquete python) y una clave ssh para conectarse. Con esto ya puedes comenzar a ejecutar tus propios playbooks de ansible.

Al escribir un playbook de ansible, que se explicará más adelante, se establece el estado deseado del servidor. Ten en cuenta que no se establece un conjunto de tareas para ejecutar cada vez, como un lenguaje informático convencional, sino que se describe un estado del servidor que ansible garantizará cada vez que se ejecute el playbook.

Ilustremos esto con un ejemplo. Considera el siguiente playbook tomado de la documentación oficial:

tasks:
- name: ensure apache is at the latest version
  yum: name=httpd state=latest

- name: write the apache config file
  template: src=/srv/httpd.j2 dest=/etc/httpd.conf
  notify:
  - restart apache

- name: ensure apache is running (and enable it at boot)
  service: name=httpd state=started enabled=yes

handlers:
  - name: restart apache
    service: name=httpd state=restarted

Aquí puedes ver tasks y handlers. Primero, veamos las tasks. Como puedes ver, cada task tiene un nombre descriptivo para saber cuál es su objetivo. Hay varios tipos de tasks para ansible, hay tasks para los administradores de paquetes como yum o apt; también hay tasks para servicios, archivos, etc.

La primera task del ejemplo, ensure apache is at the latest version, actualiza la versión de apache a su versión más reciente, pero solo, y aquí es donde ansible muestra su poder, si es necesario actualizarla. Si apache ya está actualizado, ansible no ejecuta esta task ¿por qué lo haría si la task no haría nada? Gracias a este comportamiento, ansible evita el tiempo de espera en ejecuciones de tasks redundantes o innecesarias.

Continuemos, la segunda task, write the apache config file, es una task de template; esto permite a ansible copiar un archivo a un destino dentro del servidor. El archivo no es un archivo, es una plantilla que utiliza Jinja2 para representar su contenido, por lo que puede ser dinámico. No vamos a explorar este tema en esta entrada, pero es una de las características principales y más importantes que ofrece ansible. Al igual que en la task anterior, si el archivo ya existe con el contenido que el usuario intenta copiar allí, ansible no ejecuta esta tasks ¿Por qué debería copiar un archivo ya existente?

Pero aquí aparece un factor adicional, los handlers. Como puedes ver, esta task tiene un argumento de notify. Este argumento informa a ansible que el restart apache handler debe ser notificado si esta task se ejecuta. Exploraremos esto en un momento, primero terminemos con las tasks.

La última task es asegurar que Apache se esté ejecutando (y habilitarlo al arrancar), verifica el estado del servicio apache y lo inicia si no se está ejecutando. Si el servicio ya se está ejecutando, la task se omite.

Ahora, volvamos a los handlers. Como puede ver, el restart apache handler de Apache es muy similar a la task de ensure apache is running (and enable it at boot). La única diferencia es que uno verifica que el servicio apache se está ejecutando y el otro reinicia el servicio. Entonces, ¿por qué uno es una task y el otro un handler? es porque siempre debe verificar que el servicio apache se esté ejecutando, pero no necesita reiniciar el servicio cada vez que algo sucede en el servidor.

La principal diferencia entre tasks y handlers es que ansible siempre verifica si las tasks deben ejecutarse; comprueba el estado descrito por la task y lo ejecuta dependiendo de ello. Por el contrario, ansible verifica el estado descrito por los handlers solo si se ha notificado a un handler. De lo contrario, el handler se omite.

Volvamos al ejemplo, el handler restart apache solo se ejecutará si la task write the apache config file, se ejecuta, el archivo de configuración de Apache cambia y se envía la notificación para el handler. De lo contrario, el handler no se ejecutará; y tiene sentido, sí quiero reiniciar el servicio apache si el archivo de configuración de apache cambia para aplicar las modificaciones, pero no quiero reiniciarlo si el archivo es el mismo después de que la ejecución haya finalizado.

Hay dos consideraciones importantes para los handlers. El primero, siempre se ejecutarán al final del proceso, una vez que todas las tasks hayan finalizado. La otra es que cada handler se ejecutará solo una vez, incluso si se ha notificado más de una vez.

Esta ha sido solo una vista rápida de todo el poder que ansible tiene para ofrecer. Una de las principales ventajas es que reduce los errores humanos a cero porque, una vez que hayas desarrollado tu playbook, estarás seguro de que el servidor siempre tendrá el estado deseado y no tendrás que preocuparte de olvidar realizar una tarea en él. La otra ventaja principal es que ansible, gracias a su sistema de inventario, te permite usar el mismo playbook con diferentes servidores y con diferentes consideraciones de servidor sin demasiado esfuerzo adicional.

Junto con el sistema de inventario, ansible también tiene un sistema de roles. Este permite crear conjuntos de tasks que pueden reutilizarse en diferentes playbooks. Incluso tiene una biblioteca llamada ansible galaxy donde puedes descargar roles de otras personas y otro contenido de ansible. Escribiré sobre los roles de ansible en otra entrada.

Aquí en swapps hemos ahorrado mucho tiempo automatizando nuestros desarrollos de servidor y hemos creado nuestra propia aplicación de integración continua, https://deploycloud.io/. Gracias a eso, podemos enfocarnos en lo que realmente importa mientras deploycloud maneja todas las tareas repetitivas; ahorrándonos tiempo y dinero.


Comments