Ansible

11 Templates

Ansible utilise un système de « Templates » ou modèles, permettant de créer des fichiers scripts pour la gestion des serveurs et des équipements. Ils s’appuient sur Jinja2, un gestionnaire de modèles écrit pour Python.

Les « Templates » Jinja2 permettent de gérer des boucles, des tests logiques, des listes ou des variables, ils permettent de faire des développements avancés et sont indispensables pour la gestion de la fonctionnalité ZTP (Zero Touch Provisioning) des équipements réseau.

Nous allons créer notre premier « Template » dans lequel nous allons détailler un peu plus les structures principales des boucles, des tests logiques et la définition d’une variable.

Notre premier fichier de « Template » sera nommé « myFirstTemplate.j2 ». Vous noterez l’extension « .j2 » qui désigne ce fichier comme étant au format « Jinja2 ». Les fichiers de ce type sont assez souples au niveau de la syntaxe, cependant il faut noter quelques particularités :

  • Une variable est appelée grâce à la syntaxe suivante {{ variable }}
  • Toutes les instructions (Statement) commencent et se terminent par {% … %}
  • Tous les commentaires Jinja2 commencent et se terminent pas {# … #}. Ils ne sont pas affichés en sortie de fichier.

Comme vu précédemment, Jinja2 permet de réaliser de nombreux développements avec les « Templates », notamment des boucles et des tests logiques.

Par exemple, nous allons définir une liste appelée myList :

{# Définition de notre liste #} 

{% set myList = [ 1 , 2 , 3 ] %}

{# Parcours de la liste #}
{# Pour afficher l'ensemble des valeurs présentes #} 

{% for value in myList %}

     Valeur : {{ value }}

{% endfor %}

La sortie du fichier sera alors :

    Valeur : 1
    Valeur : 2
    Valeur : 3

Il est également possible de faire des tests logiques à l’aide de Jinja et d’afficher des résultats différents en fonction du test :

{% set myList = [ 1 , 2 , 3 ] %}

{% for value in myList %}

    {% if value is divisibleby(3) %}
 
         La valeur {{ value }} est divisible par 3

    {% else %}
 
         La valeur {{ value }} n'est pas divisible par 3

{% endfor %}

La sortie du fichier sera alors :

La valeur 1 n'est pas divisible par 3
La valeur 2 n'est pas divisible par 3
La valeur 3 est divisible par 3

Note : l’exemple précédent est tiré de la documentation officielle Jinja2 [1].

Pour reprendre l’exemple de modèle proposé dans le chapitre consacré au langage Python, voici une façon d’organiser la génération de fichiers de configurations des vlans correspondant à des commutateurs. L’organisation des répertoires s’inspire des bonnes pratiques Ansible qu’il convient d’appliquer pour simplifier l’ensemble du processus.

Fichier group_vars/all/vars.yml

---
my_switches:
  - hostname: switch_1
    admin_ip: 192.168.3.251
  - hostname: switch_2
    admin_ip: 192.168.3.252
  - hostname: switch_3
    admin_ip: 192.168.3.253

my_vlans:
  - id: 2
    name: data
  - id: 3
    name: voice

Fichier InitVlans.yml

---
- name: Prepare VLANs configuration
  hosts: localhost
  gather_facts: no
  become: true
  roles:
    - {role: "CreateVlans", tags: "CV"}

Fichier roles/CreateVlans/tasks/main.yml

---
- name: Generate VLANs configuration files
  template: src=vlans.j2 dest=./{{item.hostname}}-vlans.cfg
  with_items:
    - "{{ my_switches }}"

Fichier roles/CreateVlans/templates/vlans.j2

! VLAN:
{% for vlan in my_vlans %}
vlan {{ vlan.id }} admin-state enable
vlan {{ vlan.id }} name "{{ vlan.name }}"
{% endfor %}

L’ensemble est exécuté par la simple commande :

ansible-playbook InitVlans.yml

Un fichier est généré par commutateur (switch_1-vlans.cfg, switch_2-vlans.cfg et switch_3-vlans.cfg) et le contenu est formaté selon le modèle configuré :

! VLAN:
vlan 2 admin-state enable
vlan 2 name "data"
vlan 3 admin-state enable
vlan 3 name "voice"