AnsibleVoici le seizième article de la formation Ansible. Dans mon précédent article, nous nous sommes intéressés à la gestion des Target Hosts hétérogènes. Aujourd’hui nous allons découvrir les templates qui nous permettent de personnaliser les fichiers que nous installons sur un Target Host.

Atelier pratique

Placez-vous dans le répertoire du dix-huitième atelier pratique :

$ cd ~/formation-ansible/atelier-18

Voici les cinq machines virtuelles de cet atelier :

Machine virtuelle Adresse IP
ansible 10.23.45.10
rocky 10.23.45.20
debian 10.23.45.30
suse 10.23.45.40
ubuntu 10.23.45.50

Démarrez les VM :

$ vagrant up

Connectez-vous au Control Host :

$ vagrant ssh ansible

L’environnement de cet atelier est préconfiguré et prêt à l’emploi :

  • Ansible est installé sur le Control Host.
  • Le fichier /etc/hosts du Control Host est correctement renseigné.
  • L’authentification par clé SSH est établie sur les trois Target Hosts.
  • Le répertoire du projet existe et contient une configuration de base et un inventaire.
  • Direnv est installé et activé pour le projet.
  • Le validateur de syntaxe yamllint est également disponible.

Rendez-vous dans le répertoire des playbooks :

$ cd ansible/projets/ema/playbooks/
direnv: loading ~/ansible/projets/ema/.envrc
direnv: export +ANSIBLE_CONFIG

Une page personnalisée pour Apache

Jetez un œil dans le playbook apache-01.yml, qui reprend l’installation d’Apache du précédent article. Vous connaissez déjà le module copy qui vous permet de transférer des fichiers ou des contenus sur un ou plusieurs Target Hosts :

    - name: Install custom web page
      copy:
        dest: "{{apache_document_root}}/index.html"
        mode: 0644
        content: |
          <!doctype html>
          <html>
            <head>
              <meta charset="utf-8">
              <title>Test</title>
            </head>
            <body>
              <h1>My Ansible-managed website</h1>
            </body>
          </html>

Nous allons commencer par déplacer le contenu de la page web par défaut vers un fichier externe index.html. Ansible va chercher les fichiers à transférer dans un répertoire files/ à côté du playbook :

$ pwd
/home/vagrant/ansible/projets/ema/playbooks
$ cat files/index.html
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Test</title>
  </head>
  <body>
    <h1>My Ansible-managed website</h1>
  </body>
</html>

La tâche correspondante dans apache-02.yml va ressembler à ceci :

    - name: Install custom web page
      copy:
        dest: "{{apache_document_root}}/index.html"
        mode: 0644
        src: index.html

Jusqu’ici, rien de nouveau sous le soleil. Exécutez ce playbook et vous verrez qu’aucun changement ne sera rapporté.

Dans le playbook apache-03.yml, j’ai remplacé le module copy par le module template comme ceci :

    - name: Install custom web page
      template:
        dest: "{{apache_document_root}}/index.html"
        mode: 0644
        src: index-1.html.j2

Le module template va chercher les fichiers dans un répertoire templates/ à côté du playbook :

$ cat templates/index-1.html.j2
{# templates/index-1.html.j2 #}
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>{{inventory_hostname}}</title>
  </head>
  <body>
    <h1>Welcome to {{inventory_hostname}}!</h1>
  </body>
  </head>
</html>

AstuceL’extension .j2 signifie « Jinja2 » et nous indique qu’il s’agit d’un fichier template. C’est là une convention, et rien ne vous empêche de nommer votre template index-1.html.yatahongaga. Ceci étant dit, autant utiliser quelque chose de parlant.

Exécutez le playbook ansible-03.yml :

$ ansible-playbook apache-03.yml
...
TASK [Install custom web page] *************************************
changed: [ubuntu]
changed: [debian]
changed: [rocky]
changed: [suse]
...

À présent, chacun des serveurs web devrait arborer une page par défaut personnalisée :

$ curl suse
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>suse</title>
  </head>
  <body>
    <h1>Welcome to suse!</h1>
  </body>
  </head>
</html>

Essayons d’aller un peu plus loin dans cette personnalisation :

$ cat templates/index-2.html.j2 
{# templates/index-2.html.j2 #}
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>{{inventory_hostname}}</title>
  </head>
  <body>
    <h1>Welcome to {{inventory_hostname}}!</h1>
    <h2>Here's our team:</h2>
    <ul>
    {% for host in groups['all'] %}
      <li>{{host}}</li>
    {% endfor %}
    </ul>
  </body>
  </head>
</html>

Dans l’exemple ci-dessus nous avons utilisé une boucle for pour générer la liste de tous les hôtes.

Exécutez le playbook apache-04.yml et voyez ce que ça donne au final :

Ansible Templates

Et maintenant ?

L’objectif de cet article se veut modeste : vous fournir une première démonstration de ce que l’on peut faire avec Jinja et les templates. Nous aurons l’occasion d’y revenir. Pour en savoir (beaucoup) plus, jetez un œil sur la documentation officielle :

Exercice

Dans notre précédent exercice, nous avons mis en place la synchronisation NTP avec Chrony sur nos Target Hosts, en installant le fichier de configuration ci-dessous sur chacune des quatre cibles :

# chrony.conf
server 0.fr.pool.ntp.org iburst
server 1.fr.pool.ntp.org iburst
server 2.fr.pool.ntp.org iburst
server 3.fr.pool.ntp.org iburst
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
logdir /var/log/chrony

Écrivez un playbook chrony.yml qui installe un fichier de configuration personnalisé sur vos cibles. La première ligne de commentaire devra indiquer le chemin complet vers le fichier :

  • Dans certains cas ce sera /etc/chrony/chrony.conf.
  • Dans d’autres cas ce sera simplement /etc/chrony.conf.

À vous de trouver une solution en utilisant les éléments que nous avons abordés dans cet article.

La suite au prochain numéro.


La rédaction de cette documentation demande du temps et des quantités significatives de café espresso. Vous appréciez ce blog ? Offrez un café au rédacteur en cliquant sur la tasse.

 


0 commentaire

Laisser un commentaire

Emplacement de l’avatar

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *