Cómo crear plantillas de Ansible para ahorrar tiempo de configuración

Gestionar configuraciones de múltiples servidores y entornos es un gran beneficio de usar Ansible. Pero ¿qué sucede cuando los archivos de configuración varían de un servidor a otro? En lugar de crear una configuración separada para cada servidor o entorno, deberías investigar las plantillas de Ansible.

En este tutorial, aprenderás qué son las plantillas de Ansible, cómo funcionan y cómo puedes utilizar el módulo de plantillas de Ansible para ahorrar un montón de tiempo.

Requisitos previos

Esta publicación será un tutorial paso a paso. Si deseas seguirlo, asegúrate de tener un host controlador de Ansible. Este tutorial utilizará Ansible v2.9.18

¿Qué es una plantilla de Ansible?

A veces necesitas transferir archivos de texto a hosts remotos. Estos archivos de texto suelen ser algún tipo de archivo de configuración. Si estás trabajando con un solo servidor, por ejemplo, es posible que necesites crear un archivo de configuración llamado app.conf que algún servicio utilice.

Ese archivo de configuración puede contener información específica de ese servidor, como el nombre del host, la dirección IP, etc. Dado que estás trabajando con un solo servidor, podrías crear el archivo en el controlador de Ansible y luego usar el módulo copy en un playbook para copiarlo al servidor.

Pero ¿qué pasa si tienes varios servidores web, cada uno necesitando el mismo archivo de configuración pero con valores específicos? No puedes simplemente copiar el archivo de configuración a todas las máquinas; está diseñado solo para un único servidor con un nombre de host y una dirección IP específicos, etc. Necesitas una plantilla de Ansible.

Las plantillas de Ansible te permiten definir archivos de texto con variables en lugar de valores estáticos, y luego reemplazar esas variables durante la ejecución del playbook.

¿Cómo se ve una plantilla de Ansible?

Una plantilla de Ansible es un archivo de texto construido con el lenguaje de plantillas Jinja2 con una extensión de archivo j2. Una plantilla Jinja2 se ve exactamente como el archivo de texto que te gustaría colocar en un host remoto. La única diferencia es que, en lugar de valores estáticos, el archivo contiene variables.

Por ejemplo, tal vez necesites obtener un archivo de configuración llamado app.conf en todos tus servidores web, que contenga referencias a la dirección IP de cada servidor respectivo, el host de Ansible y el usuario de Ansible. El archivo app.conf de un solo servidor puede verse como el ejemplo a continuación.

my_ip    = "192.168.0.1"
my_host  = "ANSBILECONTROL"
my_user  = "ansible_user"

No puedes copiar este archivo en cada servidor web porque cada elemento será único según la dirección IP del host remoto, el nombre del controlador de Ansible y el usuario de Ansible.

En lugar de establecer estáticamente cada uno de estos valores, una plantilla de Ansible te permite definir variables que se interpretan en tiempo de ejecución y se reemplazan en el host remoto.

A continuación, encontrarás un ejemplo del archivo de plantilla app.conf.j2. Ahora puedes ver que cada valor estático se ha reemplazado por una variable indicada con dobles llaves a cada lado. En este caso, estas variables provienen de hechos de Ansible.

Los archivos de plantilla siempre tienen la extensión de archivo J2 y suelen tener el mismo nombre que el archivo que crean en el host de destino.

my_ip    = "{{ansible_default_ipv4["address"]}}"
my_host  = "{{ansible_host}}"
my_user  = "{{ansible_user}}"

¿Cómo se crean archivos con plantillas en hosts remotos?

Una vez que has creado una plantilla, necesitas transferir ese archivo de plantilla al host remoto y “convertirlo” en el archivo de texto real de cómo debería verse. Para hacer eso, necesitas hacer referencia al archivo de plantilla en un playbook.

La mayoría de los administradores de Ansible utilizan el módulo copy para transferir archivos a hosts remotos, pero, como se mencionó anteriormente, esto no es factible con plantillas.

A continuación, puedes ver un ejemplo simple de referencia de un playbook que copia el archivo app.conf al directorio /opt en todos los hosts objetivo del playbook.

- name: copy file from local host to remote host
  copy:                               # Declaring Copy Module 
    src: "app.conf"                   # Source Location 
    dest: "/opt/app.conf"             # Destination Location on remote host

Ahora, supongamos que has “templateizado” el archivo de configuración app.conf para convertirlo en un archivo de plantilla app.conf.j2, como se cubrió en la sección anterior, en tu controlador de Ansible. Ahora necesitas asegurarte de que app.conf llegue al directorio /opt, pero con las variables reemplazadas por valores reales.

Para indicar al playbook que cree el archivo app.conf en el directorio /opt, simplemente reemplaza la referencia de copy con template, como se muestra a continuación. Cuando haces esto, Ansible invoca el módulo de plantilla para transferir la plantilla y reemplazar las variables con valores estáticos.

- name: template file to remote host
  template:                 # Ansible template module
    src: "app.conf.j2"      # This is template src i.e source location 
    dest: "/opt/app.conf"   # Destination of Remote host

Una vez que la tarea anterior en el playbook se ejecuta, Ansible copiará el archivo app.conf.j2 al directorio /opt del host remoto, reemplazará todas las variables por valores estáticos y renombrará el archivo como app.conf.

Cuando proporcionas la plantilla src con una ruta de directorio, Ansible busca plantillas en el directorio /<directorio_de_instalación_de_ansible>/files/. Si simplemente proporcionas el nombre de archivo, Ansible buscará la plantilla en lugar en el directorio /<directorio_de_instalación_de_ansible>/templates/.

Renderización de un Archivo de Configuración: Un Ejemplo de Plantilla

Ahora veamos una demostración para ver cómo configurar una plantilla de Ansible y usar el módulo de plantillas de Ansible para generar dinámicamente un archivo de configuración. En este ejemplo, estás creando un archivo llamado app.conf en el directorio /etc en un servidor llamado SRV1.

Los pasos de esta sección funcionarán para cualquier tipo de archivo de texto. El tutorial usará un archivo de configuración como ejemplo único.

1. Accede por SSH a tu host controlador de Ansible utilizando el usuario que normalmente utilizas para gestionar Ansible.

2. Crea una carpeta en tu directorio de inicio para contener los archivos de demostración de este tutorial y cambia el directorio de trabajo a esta carpeta.

mkdir ~/ansible_template_demo
cd ~/ansible_template_demo

3. Crea un archivo de plantilla llamado app.conf.j2 en el directorio que se ve como sigue.

my_ip = {{ansible_default_ipv4["address"]}}
my_host  = {{ansible_host}}
my_user  = {{ansible_user}}

También puedes usar varias variables específicas del módulo de plantillas de Ansible en tu plantilla.

4. Crea un playbook sencillo en el mismo directorio llamado mi_playbook.yml. Este playbook crea el archivo app.conf en el directorio /etc.


name: Ansible template example 
hosts: myserver 
remote_user: ubuntu   # Using Remote host as ubuntu 
tasks: 
 - name: Create the app.conf configuration file
   template:
     src: "~/ansible_template_demo/app.conf.j2"
     dest: "/etc/app.conf"
   become: true 

5. Invoca el playbook de Ansible apuntando al host remoto SRV1.

ansible-playbook my_playbook.yml --inventory SRV1
You should then see Ansible execute the playbook.

6. Ahora confirma que el archivo de configuración /etc/app.conf existe y tiene los valores esperados.

confirm the /etc/app.conf configuration file

Actualización de permisos de archivo con el módulo de plantilla

Ahora que has visto lo básico de cómo usar el módulo de plantilla, vamos a profundizar un poco más. Para esta demostración, vas a crear el mismo archivo app.conf como se mostró anteriormente. Pero esta vez, vas a establecer el propietario del archivo y los permisos en ese archivo.

Para cambiar los permisos en el archivo que crea el módulo de plantilla, debes usar tres parámetros dentro del playbook:

  • propietario – El propietario del archivo
  • grupo – El grupo al que debería pertenecer el archivo
  • modo – Los permisos. Esta cadena puede expresarse tanto en símbolos como en números octales

En modo simbólico, u representa “usuario”, g representa “grupo” y o representa “otros”.

Assumiendo que aún tienes la carpeta ~/ansible_template_demo creada desde la sección anterior, abre el playbook my_playbook.yml y reemplaza su contenido con el siguiente. En este ejemplo, Ansible establecerá el propietario y el grupo como el usuario de Ansible usando las variables de conexión. Luego, establece los permisos del archivo en 0644, lo que representa:

  • El propietario tiene permisos de lectura/escritura
  • Los usuarios en el grupo y cualquier otro tienen permisos de lectura
---
- name: Ansible file permission example
  remote_user: ubuntu
  tasks:
    - name: Create the app.conf configuration file and assign permissions
      template:
          src: "~/ansible_template_demo/app.conf.j2"
          dest: "/etc/app.conf"
	  owner: "{{ ansible_user }}"
          group: "{{ ansible_user }}"
          mode:  0644 ## OR  mode: u=rw, g=w,o=r       
      become: true

Puedes encontrar todos los parámetros disponibles del módulo de plantillas en la documentación del módulo de plantillas de Ansible.

Ahora, ejecuta el playbook nuevamente como se muestra a continuación.

ansible-playbook my_playbook.yml --inventory SRV1

Ahora puedes ver que el archivo app.conf tiene los permisos de archivo esperados asignados.

app.conf

Usando bucles para plantillas de varios archivos

A veces, un solo archivo no es suficiente; necesitas agregar varios archivos en un host remoto. En ese caso, puedes usar bucles con el módulo de plantillas. Definir un bucle utilizando el parámetro loop te permite agregar muchos archivos de texto almacenados en un directorio.

Suponiendo que aún tienes la carpeta ~/ansible_template_demo creada desde la sección anterior, deberías tener el archivo app.conf.j2 allí.

1. Crea un segundo archivo de plantilla llamado app2.conf.j2 en la carpeta ~/ansible_template_demo como se muestra a continuación.

 template_host = "{{ template_host }}"
 template_uid = "{{ template_uid }}"
 template_path = "{{ template_path }}"
 template_fullpath = "{{ template_fullpath }}"
 template_run_date = "{{ template_run_date }}"

2. Abre el archivo my_playbook.yml y reemplaza todo el contenido con el YAML a continuación. Este playbook utiliza la variable {{item}} para representar cada archivo de plantilla procesado en el bucle. El parámetro loop luego define cada uno de los archivos de plantilla para que el bucle los procese.

---
- name: Ansible file permission example 
  remote_user: ubuntu 
  tasks: 
   - name: Create the app.conf configuration file and assign permissions 
     template:   
        src: "~/ansible_template_demo/{{item}}.j2"    # Itera sobre 2 plantillas   
        dest: "/etc/{{item}}"
        owner: "{{ ansible_user }}"   
        group: "{{ ansible_user }}"   
        mode:  0644 ## O bien, modo: u=rw, g=w,o=r        
     become: true     
     loop: # Indica al módulo de plantilla que encuentre cada una de estas plantillas y las procese                                              
      - app1.conf 
      - app2.conf 

3. Ahora ejecuta el playbook nuevamente. ansible-playbook my_playbook.yml --inventory SRV1

ansible-playbook my_playbook.yml --inventory SRV1
Notice now that Ansible sees each template file and processes them accordingly.

Conclusión

Las plantillas de Ansible y el módulo de plantilla pueden ahorrarte un montón de tiempo y crear archivos de texto dinámicos en todos tus hosts remotos. El módulo de copia proporciona funcionalidad similar, pero si alguna vez necesitas crear archivos de texto dinámicos, el módulo de plantilla es tu amigo.

Source:
https://adamtheautomator.com/ansible-template/