ebenoit.info

Conventions de nommage pour Ansible

Je voulais écrire un petit quelque chose sur la façon dont je nomme les différents éléments lorsque j'utilise Ansible ; cependant, comme cela dépend en partie de la façon dont j'organise mes inventaires et mes playbooks, j'ai fini par devoir expliquer une partie de cela aussi.

Inventaire

Noms d'hôtes

J'ai tendance à ignorer la best practice communément admise, qui consiste à utiliser des noms courts pour les hôtes, et à utiliser plutôt des FQDNs. À mon avis, cela présente de nombreux avantages.

Noms des groupes

J'organise mon inventaire en hiérarchies relativement peu profondes qui correspondent à différents aspects. Tous les noms de groupes dans une telle hiérarchie, à l'exception du groupe de niveau supérieur, sont précédés d'un préfixe indiquant la hiérarchie à laquelle ils appartiennent. Par exemple, si je dois regrouper les hôtes par emplacement, je vais utiliser un groupe nommé by_location contenant des sous-groupes utilisant le préfixe loc_.

Tous les noms de groupe sont en snake case.

Rôles et tags

J'utilise la kebab-case pour les noms de rôles. En outre, je m'assure généralement que chaque rôle peut être contrôlé à l'aide d'un seul tag, qui est identique au nom du rôle.

J'organise la plupart des tâches de mes rôles en un ensemble de 5 phases.

Ces phases ne sont pas toujours toutes présentes dans un rôle donné. Si elles le sont, les phases d'installation, de configuration et d'exécution porteront respectivement les tags install, config et runtime, tandis que les préparations et la post-installation ne portent aucune étiquette. Cela permet aux phases d'un rôle d'être exécutées sélectivement de manière relativement prévisible.

Variables

Préfixe

Toutes les variables doivent être préfixées, soit par un nom de rôle, soit par un nom de groupe. Alors que la pratique communément admise consiste à utiliser un seul _ pour séparer le préfixe et le nom réel de la variable, je préfère en utiliser deux, par exemple :

my_role__variable_name: value

Le raisonnement est que, lorsqu'on en utilise un seul, un nom tel que a_b_c est ambigu : il pourrait s'agir de la variable b_c du groupe/rôle a, mais aussi de la variable c du groupe/rôle a_b. Bien que je n'aie jamais eu de collisions lorsque j'utilisais encore un seul séparateur, j'ai vu des cas d'ambiguïté à quelques reprises.

Lorsque la variable est liée à un rôle, le nom du rôle converti en snake case sera utilisé comme préfixe, comme on le voit ci-dessus avec un rôle appelé my-role.

Pour les variables fournies par des groupes, j'utiliserai le nom du groupe comme préfixe de la variable. Par exemple, si je voulais définir une variable vlan_tag qui dépende du réseau sur lequel se trouve un hôte, j'aurais le type de structure suivant :

all:
  children:
    by_network:
      children:
        net_dmz:
          vars:
            by_network__vlan_tag: 32
        net_app1:
          vars:
            by_network__vlan_tag: 33
        net_dev:
          vars:
            by_network__vlan_tag: 34

Je n'utilise que très rarement de variables liées à des hôtes. Quand c'est le cas, il s'agit d'exceptions à des éléments habituellement portés par des groupes, les noms de variables étant donc déterminés par ces derniers.

Variables privées

Quand une variable doit être considérée comme "privée" pour un rôle ou un groupe, je préfixe son nom entier avec un _ supplémentaire. Ce sera le cas pour presque toutes les variables dans le fichier vars/main.yml d'un rôle, car la plupart d'entre elles ne sont pas destinées à être utilisées en dehors du rôle qui les définit. J'utilise également cette convention pour les variables utilisées avec la clause register d'une tâche, et pour les itérateurs de boucles si item est insuffisant (par exemple pour les boucles qui incluent d'autres tâches ou rôles).

Découplage

Un rôle ne devrait à mon avis jamais utiliser une variable qui ne lui est pas explicitement destinée en dehors des host facts, car cela introduit un couplage fort entre ce rôle et la structure actuelle de l'inventaire.

Pour cette raison, j'utilise des variables de groupe pour transporter des informations communes et j'affecter leur contenu aux variables de rôle. Par exemple, si j'avais une variable db_name dans les rôles role-a et role-b qui devaient se voir attribuer la même valeur, j'obtiendrais quelque chose comme ceci dans mes variables de groupe :

srv_service__db_name: thing
role_a__db_name: "{{ srv_service__db_name }}"
role_b__db_name: "{{ srv_service__db_name }}"

Handlers

J'utilise toujours la directive listen pour mes handlers, avec un nom qui suit la même convention que les noms de variables ci-dessus. Par exemple, un handler qui redémarre le service pour un rôle nommé apache sera appelé apache__restart. Cependant, j'ajoute toujours, en plus de cet identifiant, un nom lisible par l'homme qui apparaîtra dans les journaux.

- listen: ntp__restart
  name: Restart NTP
  ansible.builtin.service:
    name: ntp
    state: restarted