En este artículo voy a demostrar cómo crear un playbook de Ansible para saber cuáles de tus servidores Debian están haciendo uso de los backports. Este ejemplo sirve para ilustrar cómo es posible extraer información de múltiples servidores al mismo tiempo utilizando comandos simples (grep
/cat
/find
) junto el módulo shell
.
Supongamos el siguiente escenario: viene un colega o líder de equipo y nos pide un listado de todos los servidores Debian que están haciendo uso de los backports. Tradicionalmente habría que conectarse uno por uno a todos los servidores, examinando el contenido del archivo /etc/apt/sources.list
y todos los archivos en el directorio /etc/apt/sources.list.d/
, una tarea que llevaría horas o incluso días. En cambio, gracias a Ansible, es posible obtener esta información de todos los servidores al mismo tiempo utilizando un simple playbook y muy rápidamente.
El módulo shell
de Ansible, permite ejecutar comandos arbitrarios en los nodos (servidores orquestrados por Ansible). PAra detectar el uso de backports es posible "grepear" la existencia de la cadena "backports" en caulquiera de los mencionados archivos (al menos una coincidencia), siempre que la línea no comience con "#" (comentarios):
grep -Rv "^#" /etc/apt/sources* | grep backports
Utilizando el módulo shell
, es posible ejecutar este comando en cada nodo y guardar el resultado en una variable mediante la palabra clave register
. El playbook, llamado "check-backports.yml", contiene el siguiente código YAML:
# Este playbook identifica cuáles de los servidores Debian están utilizando backports - hosts: debian become: yes tasks: - name: Verificar si se utilizan backports shell: 'grep -Rv "^#" /etc/apt/sources* | grep backports' register: backports failed_when: backports.rc == 2 - name: Advertir en caso de que haya coincidencias when: backports.rc < 1 debug: msg="Utiliza backports"
El playbook consta de dos tareas. La primera ejecuta el comando y almacena el resultado en la variable "backports". Se debe tener en cuenta que es necesario indicar a Ansible que la tarea falla sólo cuando el código de retorno es igual a 2 (grep
retorna 1 cuando no hubo coincidencias, lo cual no es un error en sí). Esto se hace con la sentencia failed_when
, y se puede acceder al código de retorno del resultado a través del campo "rc".
La segunda tarea del playbook simplemente registra un mensaje de debug sólo cuando el código de retorno es menor a 1 (es decir, hubo coincidencias). Esto se hace con las sentencias when
y debug
.
Veamos un ejemplo de corrida del playbook:
ansible@bastion:~/ansible_playbooks$ ansible-playbook check-backports.yml PLAY [desa-debian] ***************************************************************************************************** TASK [Gathering Facts] ************************************************************************************************* ok: [serv01.linuxito.com] ok: [serv07.linuxito.com] ok: [dbserv35.linuxito.com] ok: [h21mysql.linuxito.com] ok: [serv13.linuxito.com] ok: [wwwdevel.linuxito.com] ok: [pgprod.linuxito.com] ok: [serv20.linuxito.com] ok: [serv03.linuxito.com] ok: [dbserv05.linuxito.com] TASK [Verificar si se utilizan backports] ****************************************************************************** changed: [h21mysql.linuxito.com] changed: [serv07.linuxito.com] changed: [serv13.linuxito.com] changed: [serv01.linuxito.com] changed: [pgprod.linuxito.com] changed: [dbserv35.linuxito.com] changed: [wwwdevel.linuxito.com] changed: [serv20.linuxito.com] changed: [serv03.linuxito.com] changed: [dbserv05.linuxito.com] TASK [Advertir en caso de que haya coincidencias] ********************************************************************** skipping: [serv07.linuxito.com] skipping: [serv03.linuxito.com] skipping: [dbserv35.linuxito.com] skipping: [serv20.linuxito.com] skipping: [wwwdevel.linuxito.com] skipping: [dbserv05.linuxito.com] skipping: [serv13.linuxito.com] ok: [h21mysql.linuxito.com] => { "msg": "Utiliza backports" } ok: [pgprod.linuxito.com] => { "msg": "Utiliza backports" } ok: [serv01.linuxito.com] => { "msg": "Utiliza backports" } PLAY RECAP ************************************************************************************************************* serv07.linuxito.com : ok=2 changed=1 unreachable=0 failed=0 serv03.linuxito.com : ok=2 changed=1 unreachable=0 failed=0 serv13.linuxito.com : ok=2 changed=1 unreachable=0 failed=0 serv01.linuxito.com : ok=3 changed=1 unreachable=0 failed=0 dbserv35.linuxito.com : ok=2 changed=1 unreachable=0 failed=0 serv20.linuxito.com : ok=2 changed=1 unreachable=0 failed=0 wwwdevel.linuxito.com : ok=2 changed=1 unreachable=0 failed=0 pgprod.linuxito.com : ok=3 changed=1 unreachable=0 failed=0 h21mysql.linuxito.com : ok=3 changed=1 unreachable=0 failed=0 dbserv05.linuxito.com : ok=2 changed=1 unreachable=0 failed=0
Notar cómo la primera tarea se ejecuta en todos los servidores, y luego la segunda sólo en los que hubo coincidencias, para los cuales se muestra el mensaje de debug esperado.
Teniendo que este ejemplo es una muestra reducida de nodos (con fines didácticos), comparar el tiempo necesario para escribir este simple playbook en contraste a lo que hubiese sido recorrer todos los servidores uno por uno y de forma manual.
Referencias
- shell – Execute commands in nodes
- Conditionals - Register Variables
- Error Handling In Playbooks - Controlling What Defines Failure
- Conditionals - Applying ‘when’ to roles, imports, and includes
- debug – Print statements during execution
- Exit Status - GNU Grep
- YAML