Cómo usar variables host_vars de ansible en templates jinja2

Cómo usar variables ansible de host_vars en jinja2 templates

Que es una herramienta realmente potente nadie puede discutirlo (en cuanto a instalar y configurar se refiere). El defecto que sí que tiene, es que hay tanta cantidad de opciones que a veces es difícil hacer cosas simples como usar host_vars en jinja2 desde ansible.

Si no lo conoces muy a fondo o estás teniendo tu primer contacto, te recomiendo que le eches un ojo a este artículo sobre qué es Ansible y por qué merece la pena usarlo. También tengo en el tintero algunas cuantas ideas que compartiré en breve, así que estate atento.

Cómo definir variables para jinja2 desde host_vars de Ansible

Y por qué no usar un yml en una subcarpeta dentro del rol con un nombre variable y cargarlas desde ahí y… precisamente porque me parece mucho más cómodo, dependiendo de lo que vayas a ejecutar.

Los archivos dentro de host_vars, son precisamente yml en los que con el nombre del host a ejecutar solo tienes que indicar las variables que quieres usar. Eso sí, previsamente revisadas y usadas dentro del playload o roles.

Lo bueno de usarlas aquí, es que están todas en un mismo sitio, y no las desperdigas por los roles, por lo que a la hora de configurar un nuevo servidor, solo tocas un archivo. Como a mí me gusta que las cosas sean claras, y me ha costado un rato dar con la fórmula, te pongo el ejemplo, y cómo usarlo.

Configurar variables en ansible host_vars (incluso arrays)

Lo primero será crear el archivo dentro de home/ansible/host_vars o donde lo tengas tú instalado. En este ejemplo vamos a configurar un archivo vhosts con ansible usando un array de dominios y carpetas en host_vars. Por ejemplo para vichaunter.org.

Léete también  Como realizar una videoconferencia múltiple sin ningún software

El archivo en host_vars quedaría así:

apache2_vhosts:
  - {servername: "www.vichaunter.org", documentroot: "/var/www/vichaunterorg"}
  - {servername: "www.vichaunter.com", documentroot: "/var/www/vichauntercom"}

Si te fijas, la variable apache2_vhosts que hemos definido, es un array con varios valores. En otros lenguajes de programación como php por ejemplo sería similar a esto:

apache2_vhosts = [
    ['servername' => 'www.vichaunter.org', 'documentroot' => '/var/www/vichaunterorg'],
    ['servername' => 'www.vichaunter.com', 'documentroot' => '/var/www/vichauntercom'],
];

Ahora toca usarlos dentro de la tarea que quieras. En este caso he creado una tarea en roles/vhosts/tasks/main.yml con este contenido:

---
- name: Set apache_vhost variables
 debug: msg="apache_vhosts{{ apache2_vhosts }}"

- name: Generate all.conf vhosts file
 template:
   src: ./templates/vhosts.conf.j2
   dest: /etc/apache2/sites-available/all.conf

Para entendernos, la primera tarea será la que cogerá las variables del archivo host_vars y las pondrá en apache_vhosts. De esta forma puedes añadir cualquier otra variable que quieras pasar a templates.

La segunda tarea es la que se encarga de buscar en la carpeta roles/vhosts/templates/ el archivo vhosts.conf.j2 (si te das cuenta en el src hay un punto delante que lo convierte en ruta relativa desde el archivo main.yml.

Contenido del archivo jinja2 que usa host_vars en ansible

Ahora lo que falta es el archivo template de jinja2 o j2 que trabajará con las variables que hemos cargado en este array. Es un array porque quiero enseñarte de paso cómo hacer loops en jinja2 y usar directamente los valores del array.

Como suponemos que tenemos un par de dominios, la configuración final del archivo roles/vhosts/templates/vhosts.conf.j2 quedaría así:

NameVirtualHost *:80

{% for vhost in apache_vhosts %}
<VirtualHost *:80>
 ServerName {{ vhost.servername }}
 DocumentRoot {{ vhost.documentroot }}

{% if vhost.serveradmin is defined %}
 ServerAdmin {{ vhost.serveradmin }}
{% endif %}

 <Directory "{{ vhost.documentroot }}">
     [...tu contenido...]
 </Directory>

</VirtualHost>
{% endfor %}

El for hará que la primera variable sea la definición de cada una de las claves en apache_vhosts. Luego solo nos queda acceder como lo haríamos en un objeto de javascript con vhost.key.

Léete también  Cómo preparar una máquina para controlarla con Ansible

He puesto también una condición if, para que tengas un ejemplo de cómo configurar porciones que aparezcan solo en caso de que algunas variables existan.

Conclusión

Configurar virtualhost de apache con jinja2 y ansible teniendo varios dominios como variables es una cosa bastante sencilla una vez lo tienes claro como en este tuto.

El problema es cuando intentas utilizar el comando vars: y te deja error. Yo no he conseguido cargar las variables de otra manera, pero si sabes cómo hacerlo, o puedes sugerir una mejor forma de gestionar varios vhosts desde un archivo de configuración para cada servidor déjame un comentario.

También si quieres compartir para qué utilizas tú ansible, y no te olvides de compartir.


AYUDANOS a poder seguir dando respuestas. Te podemos echar una mano y tú también a nosotros, símplemente dale a me gusta.