AnsibleVoici le dixième article de la formation Ansible. Dans mon précédent article, nous avons découvert les playbooks et leur fonctionnement de base. Aujourd’hui nous allons nous servir de cette compétence toute fraîche pour installer un serveur web simple avec Apache dans un réseau de machines sous Debian.

Non, ce n’est pas encore un « vrai » serveur web de production, même si nous allons dans la bonne direction. Vous vous doutez bien que cette première installation d’un serveur web avec Ansible aura tout d’abord une visée pédagogique.

Un serveur web simple avec Ansible

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

$ cd ~/formation-ansible/atelier-09

Voici les quatre machines virtuelles de cet atelier :

Machine virtuelle Adresse IP
control 10.23.45.10
target01 10.23.45.20
target02 10.23.45.30
target03 10.23.45.40

Toutes ces VM tournent sous Debian. Démarrez-les :

$ vagrant up

Connectez-vous au Control Host :

$ vagrant ssh control

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 du projet :

$ cd ansible/projets/ema/
direnv: loading ~/ansible/projets/ema/.envrc
direnv: export +ANSIBLE_CONFIG
$ ls -l
total 12
-rw-r--r-- 1 vagrant vagrant   65 Sep 19 11:13 ansible.cfg
-rw-r--r-- 1 vagrant vagrant  135 Sep 19 11:13 inventory
drwxr-xr-x 2 vagrant vagrant 4096 Sep 19 11:13 playbooks

L’inventaire des machines définit un groupe [debian] avec les trois Target Hosts :

$ cat inventory 
[debian]
target01
target02
target03

[debian:vars]
ansible_python_interpreter=/usr/bin/python3
ansible_user=vagrant
ansible_become=yes

Testez la connectivité à vos cibles :

$ ansible debian -m ping
target01 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
target02 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
target03 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

Maintenant que c’est réglé, nous pouvons éditer un fichier playbooks/apache-01.yml. Pour commencer, nous allons définir les hôtes concernés et introduire la section des tâches à effectuer :

---  # apache-01.yml

- hosts: debian

  tasks:

Sur les systèmes de la famille Debian, la première chose à faire avant d’installer un paquet consiste à mettre à jour les informations sur les paquets. Vous connaissez probablement les commandes respectives apt update (en mode interactif) ou apt-get update (à utiliser dans un script).

Dans le contexte d’Ansible, c’est le module apt qui se chargera de cette opération :

---  # apache-01.yml

- hosts: debian

  tasks:

    - name: Update package information
      apt:
        update_cache: true

AstuceÀ partir de là, ce n’est peut-être pas une mauvaise idée de vérifier la syntaxe YAML de votre playbook à l’aide du validateur de syntaxe. Si la commande yamllint apache-01.yml ne vous retourne rien, c’est que tout est bon. Prenez l’habitude de faire ce genre de test de temps en temps.

Lancez l’exécution du playbook et appréciez le résultat :

$ ansible-playbook apache-01.yml 

PLAY [debian] ************************************************************************

TASK [Gathering Facts] ***************************************************************
ok: [target01]
ok: [target02]
ok: [target03]

TASK [Update package information] ****************************************************
changed: [target01]
changed: [target02]
changed: [target03]

PLAY RECAP ***************************************************************************
target01   : ok=2  changed=1  unreachable=0  failed=0  skipped=0  rescued=0  ignored=0   
target02   : ok=2  changed=1  unreachable=0  failed=0  skipped=0  rescued=0  ignored=0   
target03   : ok=2  changed=1  unreachable=0  failed=0  skipped=0  rescued=0  ignored=0

Le paramètre cache_valid_time indique la durée en secondes pendant laquelle le cache de paquets sera considéré comme « suffisamment frais » :

---  # apache-01.yml

- hosts: debian

  tasks:

    - name: Update package information
      apt:
        update_cache: true
        cache_valid_time: 3600

Cette opération a considérablement amélioré l’idempotence du playbook :

$ ansible-playbook apache-01.yml 

PLAY [debian] ************************************************************************

TASK [Gathering Facts] ***************************************************************
ok: [target01]
ok: [target02]
ok: [target03]

TASK [Update package information] ****************************************************
ok: [target01]
ok: [target02]
ok: [target03]

PLAY RECAP ***************************************************************************
target01   : ok=2  changed=0  unreachable=0  failed=0  skipped=0  rescued=0  ignored=0   
target02   : ok=2  changed=0  unreachable=0  failed=0  skipped=0  rescued=0  ignored=0   
target03   : ok=2  changed=0  unreachable=0  failed=0  skipped=0  rescued=0  ignored=0

L’installation à proprement parler s’effectue également grâce au module apt :

---  # apache-01.yml

- hosts: debian

  tasks:

    - name: Update package information
      apt:
        update_cache: true
        cache_valid_time: 3600

    - name: Install Apache
      apt:
        name: apache2

Une fois qu’Apache est installé, il faut démarrer le service correspondant et activer son lancement au démarrage du système. Avec Ansible, c’est le module service qui se charge de ce genre d’opération :

    - name: Start & enable Apache
      service:
        name: apache2
        state: started
        enabled: true

AstuceCette dernière opération n’est pas vraiment nécessaire sur les systèmes de la famille Debian, étant donné que le lancement du service et l’activation au démarrage est gérée par les scripts de post-installation du paquet. En revanche, vous ne trouverez pas ce genre de comportement avec d’autres distributions comme Rocky ou SUSE. Ce n’est donc pas forcément une mauvaise d’en parler ici.

Pour ajouter la cerise sur le gâteau, nous pouvons remplacer la page par défaut du serveur web par notre propre version personnalisée. Le module copy nous permet d’effectuer ce genre d’opération. Simplement, au lieu d’indiquer un fichier source avec le paramètre src, nous utilisons ici la notation en ligne avec le paramètre content pour plus de lisibilité. Notez le bloc YAML introduit par | et qui permet de caser un texte pas trop long :

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

Voici le playbook dans son intégralité :

---  # apache-01.yml

- hosts: debian

  tasks:

    - name: Update package information
      apt:
        update_cache: true
        cache_valid_time: 3600

    - name: Install Apache
      apt:
        name: apache2

    - name: Start & enable Apache
      service:
        name: apache2
        state: started
        enabled: true

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

Exécutez-le :

$ ansible-playbook apache-01.yml

Ouvrez un navigateur web et admirez le résultat en fournissant l’URL de l’une des cibles :

Ansible Apache

Alternativement, vous pouvez vérifier le bon fonctionnement de votre configuration en invoquant curl depuis le Control Host comme ceci :

$ curl target01
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Test</title>
  </head>
  <body>
    <h1>My first Ansible-managed website</h1>
  </body>
</html>

La commande ansible-playbook offre une multitude d’options pour l’exécution :

$ ansible-playbook --help | less

AstucePlutôt que de vous assommer avec tout ça, je vais vous en présenter une seule dont je me sers très régulièrement.

Admettons que je veuille modifier le contenu de ma page web personnalisée :

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

Au lieu de revenir à la case départ et d’exécuter le playbook depuis le tout début, je peux très bien définir la tâche de départ grâce à l’option --start-at-task. Fort heureusement, cette option accepte les jokers comme * par exemple :

$ ansible-playbook apache-01.yml --start-at-task="*page*"

PLAY [debian] ************************************************************************

TASK [Gathering Facts] ***************************************************************
ok: [target02]
ok: [target03]
ok: [target01]

TASK [Install custom web page] *******************************************************
changed: [target01]
changed: [target03]
changed: [target02]

PLAY RECAP ***************************************************************************
target01   : ok=2  changed=1  unreachable=0  failed=0  skipped=0  rescued=0  ignored=0   
target02   : ok=2  changed=1  unreachable=0  failed=0  skipped=0  rescued=0  ignored=0   
target03   : ok=2  changed=1  unreachable=0  failed=0  skipped=0  rescued=0  ignored=0

Si l’utilité de cette option ne vous apparaît pas tout de suite, dites-vous que vous serez contents de la connaître le jour où votre playbook comptera une bonne centaine de tâches à effectuer et que vous n’avez pas envie d’attendre cinq à dix minutes pour chaque petite modification.

Quittez le Control Host :

$ exit

Supprimez toutes les VM :

$ vagrant destroy -f

Exercice

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

$ cd ~/formation-ansible/atelier-10

Voici les quatre 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

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 du projet :

$ cd ansible/projets/ema/
direnv: loading ~/ansible/projets/ema/.envrc
direnv: export +ANSIBLE_CONFIG
$ ls -l
total 8
-rw-r--r--. 1 vagrant vagrant  65 Sep 19 14:26 ansible.cfg
-rw-r--r--. 1 vagrant vagrant 128 Sep 19 14:26 inventory
drwxr-xr-x. 2 vagrant vagrant   6 Sep 19 14:26 playbooks

Écrivez trois playbooks :

  • Un premier playbook ansible-debian.yml qui installe Apache sur l’hôte debian avec une page personnalisée Apache web server running on Debian Linux.
  • Un deuxième playbook ansible-rocky.yml qui installe Apache sur l’hôte rocky avec une page personnalisée Apache web server running on Rocky Linux.
  • Un troisième playbook ansible-suse.yml qui installe Apache sur l’hôte suse avec une page personnalisée Apache web server running on SUSE Linux.

Voici quelques pistes de réflexion :

  • Pas la peine de rafraîchir le cache de paquets sous Rocky Linux et SUSE.
  • Apache n’a pas forcément le même nom sur ces distributions.
  • La même chose vaut pour le service correspondant.
  • Rocky Linux utilise le gestionnaire de paquets dnf.
  • SUSE Linux utilise le gestionnaire de paquets zypper.
  • Les modules de gestion de paquets correspondants portent le même nom.
  • L’emplacement de la page web par défaut (directive DocumentRoot) peut varier.
  • J’ai supprimé le pare-feu FirewallD installé par défaut sous Rocky Linux pour ne pas trop vous embrouiller.

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.

 

Catégories : Formation

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 *