En las anteriores entradas de esta serie, hemos analizado como crear un proyecto de Ansible siguiendo la estructura de directorios recomendada. Esto nos llevaba a la creación de playbooks mediante los cuales, podíamos ejecutar múltiples tareas de forma sencilla aprovechando la estructura de directorios recomendada, ya que Ansible es capaz de utilizarla para simplificar todo el proceso.
Como vimos, esta estructura nos permite organizar la información necesaria para la correcta ejecución del playbook, ficheros estáticos, plantillas, definición de variables, etc... de forma simple y repetible. Recordemos que la estructura que definimos era algo similar a lo siguiente:
Estructura básica de proyecto. |
Siguiendo esta estructura, por tanto, podemos hacer playbooks complejos para poder realizar tareas en diferentes tipos de hosts, por ejemplo servidores web, servidores de aplicaciones y servidores de bases de datos. Además podemos aplicar configuraciones, que por ejemplo sean comunes a los tres grupos de hosts, y posteriormente aplicar las configuraciones correspondientes a cada grupo de hosts. Evidentemente podemos repetir esto tantas veces como tipos o grupos de hosts tengamos que configurar o bien podemos aprovechar otra característica de Ansible denominada roles.
Básicamente, podríamos decir que un rol es un proyecto de Ansible que aplica a un tipo o grupo de hosts. Siguiendo la estructura presentada, un rol contendrá todos los ficheros, templates, tareas, etc.. que solo aplican a dicho grupo de hosts, dada por una estructura de directorios similar a la ya expuesta. Esta estructura se repetirá por cada uno de los roles existentes.
Podemos verlo, de forma simplificada, del siguiente modo:
Proyecto de Ansible y roles. |
Como podemos ver, añadimos una carpeta roles a nuestro proyecto y dentro de la misma, una carpeta por cada uno de los roles. Cada uno de estos roles se corresponderán con cualquier clasificación que pueda existir en nuestro entorno, ya sean tipos de servidores, acciones o tareas a realizar, etc...
Estructura básica de un rol. |
Teniendo en cuenta lo expuesto en anteriores entradas de esta serie de posts, es fácil imaginar cual es el objetivo de cada una de las carpetas que forman un rol:
- En la carpeta files se almacenarán los ficheros estáticos que es necesario copiar a los hosts de destino.
- La carpeta handlers contendrá un fichero main.yaml, donde podremos definir cada uno de los handlers que se utilizarán a lo largo del playbook.
- La carpeta tasks es la carpeta principal del rol y contiene, al menos, el fichero main.yaml con todas las tareas que se aplicarán al rol.
- En la carpeta templates podremos almacenar todas las plantillas Jinja correspondientes a ficheros cuyo contenido varía, las cuales copiaremos a los hosts de destino mediante el módulo ansible.builtin.template.
- La carpeta vars contendrá un fichero main.yaml, donde podremos especificar variables que son exclusivas del rol.
Con estas carpetas básicas, podemos definir un rol el cual, por tanto, podemos ver como una plantilla que siempre aplicará de igual manera a nuestros objetivos, sean estos hosts a configurar, acciones de un proceso batch, etc...
Al usar roles, el fichero principal del proyecto cambia para indicar que roles deben ejecutarse y sobre que hosts. Por ejemplo, en el caso de estar configurando un grupo de hosts para construir un cluster de kubernetes, podríamos tener un playbook general similar al siguiente:
Uso de roles. |
Teniendo en cuenta esto, es sencillo poder reutilizar los roles en otros proyectos con solo replicar el contenido de los mismos, así, en el ejmplo indicado:
- El rol common puede encargarse de configurar la red, nombres de hosts, instalación de paquetes, hardening, en todos los hosts que formarán el cluster.
- El rol masters se encargará de crear el control plane con los hosts miembros del grupo masters, realizando el bootstrapping del cluster y añadiendo el resto de nodos master al cluster.
Si fijamos la lista de paquetes a instalar en el rol common como una variable propia del rol, que almacenaríamos en la subcarpeta vars de dicho rol, podríamos reutilizar el rol completo para otro proyecto.
En resumen, el uso de roles es la manera más potente y flexible que proporciona Ansible para realizar tareas complejas que implican muchos hosts, permitiendo además reutilizar el código que desarrollemos para otros proyectos.