Comprendre la Structure d’un Playbook Ansible Part 1.2

ansible-playbook
ansible-playbook

Dans ce tutoriel, nous allons explorer la structure fondamentale d’un playbook Ansible, qui est essentiel pour automatiser des tâches systèmes et le déploiement d’applications. Un playbook Ansible peut être comparé à un script, définissant des actions spécifiques à réaliser sur un ensemble de machines distantes. vous pouvez également voir les articles précédant parlant d’ansible tels que : Maximiser l’Efficacité de Vagrant : Configuration Avancée et Intégration de Services Part 1.2 ou Automatisation de l’Infrastructure avec Vagrant et Ansible Part 1.1 ou Ansible Part 1: Introduction à la Puissance de l’Automatisation

1. Introduction

Un playbook Ansible commence toujours par l’en-tête « — » et fini par « … » comme l’exemple suivant :

---
action 1
action 2
action 3
action 4
...

Il est crucial de comprendre les principaux éléments qui composent un playbook pour créer des automatisations efficaces et maintenables.

2. Les Éléments Clés d’un Playbook

2.1. Nom de la Tâche (- name)

Le nom de la tâche est une description de l’action globale du playbook. Il est fortement recommandé d’utiliser cette annotation pour faciliter le suivi des exécutions lors du débogage.

- name: Mon Playbook d'Automatisation

L’option –start-at-task <nom_task> permet de commencer le playbook à une tâche spécifique défini par le champ name.

2.2. Machines Cibles (hosts:)

La section hosts spécifie les machines sur lesquelles les tâches seront exécutées. Vous pouvez définir des groupes, des adresses IP spécifiques, ou le groupe « all » qui prend toutes les machines dans l’inventaire.

hosts: all

ou

hosts: bullseye, focal

ou « web » serveur est un groupe

hosts: web

Patterns d’inclusion et d’exclusion:

  • Inclut toutes les machines du groupe database qui appartiennent également à l’environnement stagging.
hosts: database:&stag
  • Exclut toutes les machines du groupe database qui appartiennent à l’environnement prod.
hosts: database:!prod
  • Inclut toutes les machines des groupes database et database_recette.
hosts: database:database_recette
  • Inclut toutes les machines dont le nom d’hôte se termine par .laeltirnan.com.
hosts: *.laeltirnan.com
  • Inclut les machines web1 à web100.
hosts: web[1:100]
  • Inclut toutes les machines dont le nom d’hôte contient .fr ou .com.
hosts: laeltirnan.(fr|com)

Exemples d’utilisation:

  • Exécute une tâche sur les machines dev et stagging qui correspondent aux machines de la base de données et n’appartiennent pas au groupe prod.
host: dev:stagging:&database:!prod 

Obtention des faits:

- name: Récupère les Facts de la machine
  setup:

Déclenchement des notifications:

  • Ajoutez la clé listen: <nom_de_l'événement> dans le handler.
  • Si le notify a le même nom que le handlers: name ou handlers: listen, il sera déclenché.

Remarque: Ce résumé est concis et ne couvre pas tous les aspects des patterns d’hôtes dans Ansible. Pour plus d’informations, référez-vous à la documentation officielle d’Ansible.

2.3. Variables (vars:)

Les variables contiennent des données à charger en mémoire avant l’exécution des tâches. Cela inclut souvent les facts Ansible ou des valeurs configurables. Vous pouvez définir des variables en dur dans le playbook ou utiliser des fichiers qui stockeront toute vos variables.

vars:    
  tls_dirs:  /etc/nginx/ssl 
  key_file: nginx.key 
  conf_file: /etc/nginx/sites-available/default
  server_name: localhost

On les appellera sous la forme de valeurs variables {{ tls_dirs}} qui donnera la réponse /etc/nginx/ssl, souvent utilisées dans les templates et les playbook (voir même playbook).

2.4. Utilisateur d’Exécution (become:)

L’option become indique sous quel utilisateur les tâches seront exécutées. Par exemple, become: yes utilise l’utilisateur « ansible« , tandis que become_user: toto utilise « toto ». Si aucune option n’est spécifiée pour le become_user, l’utilisateur root est utilisé par défaut.

become: yes

ou

become_user: toto

3. Les caractéristiques Essentielles d’un Playbook

Introduction

Nous allons explorer en détail les composants fondamentaux d’un playbook Ansible, qui peut être envisagé comme un script d’automatisation. Comprendre ces éléments est crucial pour créer des automatisations efficaces et éviter les pièges courants.

Le langage des playbooks Ansible est inspiré de Python.

3.1. Commentaires

Les commentaires commencent par # et sont utiles pour documenter le code et faciliter la compréhension.

3.2. Indentations et Espaces

Le code est indenté de manière standard avec deux espaces. Chaque tâche ou section doit être suivie d’un saut de ligne.

3.3. Valeurs Booléennes

Les valeurs booléennes peuvent être exprimées de différentes manières, telles que True, true, yes, On, et leurs équivalents négatifs.

3.4. Caractères

Les chaînes de caractères peuvent contenir des espaces et sont généralement entourées de guillemets doubles ou d’underscores. Il est conseillé d’éviter d’utiliser des guillemets pour les valeurs booléennes.

3.5. Listes

Les listes peuvent être déclarées de deux manières, avec ou sans crochets. Par exemple,

mes_courses: [lait, cereale, chocolat]

ou

mes_courses:
  - lait
   - cereale
  - chocolat

3.6. Dictionnaires

Les dictionnaires sont utilisés pour structurer les données tels que la sections task ou des modules, par exemple,

devops_tools: {configuration: ansible, provisionning: terraform}

ou

devops_tools: 
  configuration: 
    ansible
  provisionning: 
    terraform

3.7 Modules et Arguments

Les modules sont des scripts exécutés sur la machine cible avec des arguments structurés sous forme de dictionnaire. Par exemple, le module copy nécessite src, dst, et d’autres arguments optionnelle tels que mode, backup, remote_src.

Pour en savoir plus sur les module :

ansible-doc <nom_moduble>

ou

ansible-doc -l | grep ^apt

3.8 Combinaison de Structures

Les playbooks peuvent inclure des combinaisons complexes de listes et de dictionnaires, ou des valeurs booléennes imbriquées. Exemple le plus courant: une liste qui contient des dictionnaires qui contient une autre liste de dictionnaire sans jamais s’arrêter.

#on commence par une liste de dictionnaire
- clé: Valeur
  clé: #list
    - valeur1
    - valeur2
    - valeur3
    - valeur4
  clé: #list de dictionnaire
    - clé: valeur
      clé: #list de dictionnaire
        clé: valeur
        clé: valeur
        clé: valeur
      clé:
        - valeur
        - valeur
      clé: valeur
    - clé: valeur
      clé:
        clé: valeur
        clé: true
      clé: valeur

Ce qui donne en exemple concret

---
- name: Mon Playbook d'Automatisation
  hosts:
    - 192.168.56.2
    - 192.168.56.3
    - 192.168.56.4
    - 192.168.56.5
  tasks:
    - name: Copy TLS files
      copy:
        src: "{{ item }}"
        dest: "{{ tls_dir }}"
        mode: 0600
      loop:
        - "{{ key_file }}"
        - "{{ cert_file }}"
      notify: Restart nginx
    - name: Ensure nginx is installed
      package:
        name: nginx
        update_cache: true
      notify: Restart nginx

4. Astuces Pratiques

4.1 Quotes et Deux Points

L’utilisation correcte des guillemets et des deux-points est essentielle pour la bonne exécution d’un playbook. Par exemple, pour éviter des erreurs,

- name: Exécuter une commande
  command: {{ app }} -a foo

utilisez

- name: Exécuter une commande
  command: "{{ app }} -a foo"

Si vous souhaitez mettre des double quote « , vous pouvez le faire en passant par de simple quote ‘ et vice versa

- name: Exécuter une commande
  debug:
    msg: "Je comprends les playbooks d'après cette article"

4.2 Templates

Les fichiers de modèle Jinja (.j2) utilisent une syntaxe particulière classés dans un dossier « template » pour les variables et sont utiles pour la configuration répétée de fichiers avec des valeurs variables. On déploiera du même fichier toute la configuration en changeant les variables.

Exemple :

Bonjour {{ name}}, votre abonnement du {{ date_started}} au {date_ended}} viens de prendre fin sur le {{ package_type }} dans le {{ serveur_name }}. Veuillez nous joindre au {{ agency_number }}

4.3 Boucles (Loop)

Les boucles peuvent être utilisées pour itérer sur des tâches avec des éléments de liste changeants. Dans cet exemple, chaque élément de la liste nginx_sites a trois variables : name, config_file, et document_root. Le playbook utilise la tâche debug à l’intérieur d’une boucle pour afficher ces détails pour chaque itération.

---
- name: Exemple de Playbook avec Loop et Variables
  hosts: localhost
  gather_facts: false
  vars:
    nginx_sites:
      - name: site1
        config_file: site1.conf
        document_root: /var/www/site1
      - name: site2
        config_file: site2.conf
        document_root: /var/www/site2
      - name: site3
        config_file: site3.conf
        document_root: /var/www/site3
  tasks:
    - name: Afficher les détails des sites Nginx
      debug:
        msg: "Site Name: {{ item.name }}, Config File: {{ item.config_file }}, Document Root: {{ item.document_root }}"
      loop: "{{ nginx_sites }}"

4.4 Handlers

Les handlers s’exécutent à la fin des tâches et sont utiles et fréquemment utiliser pour des actions telles que les redémarrages de services ou les reboots. Chacune de ces tâches utilise la clause notify pour déclencher le ou les handlers associés après l’exécution réussie de la tâche.

Exemple :

---
- name: Exemple de Playbook avec Handlers
  hosts: all
  become: true
  tasks:
    - name: Modifier un fichier de configuration
      template:
        src: nginx.conf.j2
        dest: /etc/my_config.conf
      notify:
        - Redémarrer le service
    - name: Installer un paquet
      package:
        name: nginx
        state: present
      notify:
        - Redémarrer le service
  handlers:
    - name: Redémarrer le service
      service:
        name: nginx
        state: restarted
    - name: Rebooter la machine
      command: reboot
      async: 1
      poll: 0
      listen: "Redémarrer le service"

L’utilisation de async: 1 et poll: 0 dans le handler de reboot est une mesure de sécurité pour éviter que le playbook ne reste bloqué pendant le redémarrage. Cela permet au playbook de continuer son exécution sans attendre la fin du redémarrage.

Il existe une méthode permettant d’exécuter le handler au milieux du script, grâce à la commande :

- name : Restart nginx
  meta: flush_handlers

3.v. Validation Syntaxique

Des outils tels que ansible-playbook --syntax-check et ansible-lint permettent de valider la syntaxe des playbooks.

En résumé, un playbook Ansible a la structure suivante pour ce fichier « playbook.yml » :

---
- name: Mon Playbook d'Automatisation
  hosts: all
  vars:
    tls_dirs: /etc/nginx/ssl
    key_file: nginx.key
    conf_file: /etc/nginx/sites-available/default
    server_name: localhost
  become: yes
  # Ajoutez ici vos tâches Ansible
  tasks:
    - name: Ma Première Tâche
      # ... détails de la première tâche ...
    - name: Ma Deuxième Tâche
      # ... détails de la deuxième tâche ...

Une fois définit, nous pouvons le tester sur la ligne de commande (chaque ligne correspond à une méthode de vérification avec en derniers commande la verification du fichier d’inventory) :

ansible-playbook --syntax-check playbook.ymlansible-lint playbook.ymlyamllint playbook.yml
ansible-inventory --host web -i inventory/serveur.ini

4. Conclusion

En conclusion, ce tutoriel nous a plongés dans l’univers des playbooks Ansible, des scripts puissants utilisés pour automatiser des tâches système et le déploiement d’applications sur des machines distantes. Nous avons exploré en détail les composants essentiels d’un playbook, en mettant l’accent sur la structure de base, les variables, les tâches, et d’autres éléments clés.

La structure d’un playbook, marquée par l’en-tête  » —  » et la mention des tâches sous la forme d’une liste, offre une approche claire et organisée. Les différentes sections, telles que le nom de la tâche, les machines cibles, les variables, et le rôle de l’utilisateur d’exécution, sont autant d’éléments cruciaux pour orchestrer des opérations avec précision.

Nous avons également abordé des astuces pratiques, notamment l’utilisation correcte des guillemets et des deux-points, la création de boucles pour itérer sur des listes de données variables, l’intégration de modèles pour la configuration répétée de fichiers, et l’incorporation de gestionnaires (handlers) pour des actions post-tâches, telles que les redémarrages et les reboots.

Enfin, des outils de validation syntaxique tels qu’ansible-playbook –syntax-check, ansible-lint, et yamllint ont été présentés comme des alliés précieux pour garantir la conformité et la qualité des playbooks.

En adoptant les concepts et les bonnes pratiques détaillés dans ce tutoriel, vous êtes désormais prêt à créer des playbooks Ansible robustes et efficaces pour automatiser vos infrastructures et simplifier vos opérations de gestion système. Que vos tâches soient simples ou complexes, Ansible offre une flexibilité et une puissance inégalées pour répondre à vos besoins d’automatisation. Pour aller plus loin voici la documentation officielle d’ansible : https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_intro.html Inspirer du livre ANSIBLE Up & Running

Automation Experts

Rejoignez-nous pour une newsletter exclusive sur l'automatisation des experts informatique !

Obtenez les dernières tendances, astuces et outils pour optimiser vos processus, accélérer vos projets et libérer tout le potentiel de l'automatisation dans le monde de la technologie. Abonnez-vous dès maintenant pour rester à la pointe de l'innovation et transformer votre manière de travailler."

Comments

No comments yet. Why don’t you start the discussion?

    Alors tu en pense quoi de cette article ? Dis-moi tous..